day 4-1¶
このノートブックの実行例はこちら(HTML版)で確認できます
0. 準備¶
0.1 必要なパッケージのインストール¶
%%capture
!sudo apt-get update
!sudo apt-get install -y automake autoconf perl libtool graphviz libgraphviz-dev
!pip install -U japanize_matplotlib pyvis pygraphviz mca
教材のダウンロード
!git clone https://github.com/haradatm/lecture-gssm2025
Cloning into 'lecture-gssm2025'... remote: Enumerating objects: 152, done. remote: Counting objects: 100% (54/54), done. remote: Compressing objects: 100% (37/37), done. remote: Total 152 (delta 23), reused 42 (delta 15), pack-reused 98 (from 2) Receiving objects: 100% (152/152), 79.00 MiB | 10.77 MiB/s, done. Resolving deltas: 100% (60/60), done.
!ln -s lecture-gssm2025/notebooks/gssm_utils.py .
0.2 MeCab インストール (時間目安: 約3分)¶
%%time
!bash lecture-gssm2025/scripts/install_mecab.sh >> install_mecab.log 2>&1
!tail -n 1 install_mecab.log
Successfully installed mecab-python-0.996 CPU times: user 2.23 s, sys: 388 ms, total: 2.62 s Wall time: 3min 53s
0.3 CaboCha インストール (時間目安: 約4分)¶
%%time
!bash lecture-gssm2025/scripts/install_cabocha.sh >> install_cabocha.log 2>&1
!tail -n 1 install_cabocha.log
Successfully installed cabocha-python-0.69 CPU times: user 3.92 s, sys: 572 ms, total: 4.49 s Wall time: 6min 9s
0.4 セッションの再起動¶
import os
os.kill(os.getpid(), 9)
セッションの再起動後は,以下のセルから実行してください. 注意: これより前のセルを再度実行する必要はありません!
0.5 辞書登録¶
追加したい形態素の情報を CSV ファイル(user_dic.csv)に追記する
!echo '"泉質",-1,-1,1,名詞,一般,*,*,*,*,泉質,センシツ,センシツ,USER"' >> ./tools/usr/local/lib/mecab/dic/ipadic/user_dic.csv
!echo '"海鮮丼",-1,-1,1,名詞,一般,*,*,*,*,海鮮丼,カイセンドン,カイセンドン,USER"' >> ./tools/usr/local/lib/mecab/dic/ipadic/user_dic.csv
!echo '"スカイツリー",-1,-1,1,名詞,一般,*,*,*,*,スカイツリー,スカイツリー,スカイツリー,USER"' >> ./tools/usr/local/lib/mecab/dic/ipadic/user_dic.csv
!echo '"バスタオル",-1,-1,1,名詞,一般,*,*,*,*,バスタオル,バスタオル,バスタオル,USER"' >> ./tools/usr/local/lib/mecab/dic/ipadic/user_dic.csv
!cat ./tools/usr/local/lib/mecab/dic/ipadic/user_dic.csv
"湯畑",-1,-1,1,名詞,一般,*,*,*,*,湯畑,ユバタケ,ユバタケ,USER" "泉質",-1,-1,1,名詞,一般,*,*,*,*,泉質,センシツ,センシツ,USER" "海鮮丼",-1,-1,1,名詞,一般,*,*,*,*,海鮮丼,カイセンドン,カイセンドン,USER" "スカイツリー",-1,-1,1,名詞,一般,*,*,*,*,スカイツリー,スカイツリー,スカイツリー,USER" "バスタオル",-1,-1,1,名詞,一般,*,*,*,*,バスタオル,バスタオル,バスタオル,USER"
CSVファイル(user_dic.csv)をコンパイルして辞書(user.dic)を作成する
!./tools/usr/local/libexec/mecab/mecab-dict-index \
-d ./tools/usr/local/lib/mecab/dic/ipadic \
-u ./tools/usr/local/lib/mecab/dic/ipadic/user.dic \
-f utf-8 -t utf-8 \
./tools/usr/local/lib/mecab/dic/ipadic/user_dic.csv
reading ./tools/usr/local/lib/mecab/dic/ipadic/user_dic.csv ... 5 emitting double-array: 20% |######## | emitting double-array: 40% |################# | emitting double-array: 60% |######################### | emitting double-array: 80% |################################## | emitting double-array: 100% |###########################################| done!
0.6 確認¶
import MeCab
tagger = MeCab.Tagger("-r ./tools/usr/local/etc/mecabrc")
print(tagger.parse("この泉質は極上です"))
print(tagger.parse("この海鮮丼は美味しいです"))
print(tagger.parse("近くにスカイツリーがあります"))
print(tagger.parse("浴室にバスタオルがありません"))
この 連体詞,*,*,*,*,*,この,コノ,コノ 泉質 名詞,一般,*,*,*,*,泉質,センシツ,センシツ,USER" は 助詞,係助詞,*,*,*,*,は,ハ,ワ 極上 名詞,一般,*,*,*,*,極上,ゴクジョウ,ゴクジョー です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス EOS この 連体詞,*,*,*,*,*,この,コノ,コノ 海鮮丼 名詞,一般,*,*,*,*,海鮮丼,カイセンドン,カイセンドン,USER" は 助詞,係助詞,*,*,*,*,は,ハ,ワ 美味しい 形容詞,自立,*,*,形容詞・イ段,基本形,美味しい,オイシイ,オイシイ です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス EOS 近く 名詞,副詞可能,*,*,*,*,近く,チカク,チカク に 助詞,格助詞,一般,*,*,*,に,ニ,ニ スカイツリー 名詞,一般,*,*,*,*,スカイツリー,スカイツリー,スカイツリー,USER" が 助詞,格助詞,一般,*,*,*,が,ガ,ガ あり 動詞,自立,*,*,五段・ラ行,連用形,ある,アリ,アリ ます 助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス EOS 浴室 名詞,一般,*,*,*,*,浴室,ヨクシツ,ヨクシツ に 助詞,格助詞,一般,*,*,*,に,ニ,ニ バスタオル 名詞,一般,*,*,*,*,バスタオル,バスタオル,バスタオル,USER" が 助詞,格助詞,一般,*,*,*,が,ガ,ガ あり 動詞,自立,*,*,五段・ラ行,連用形,ある,アリ,アリ ませ 助動詞,*,*,*,特殊・マス,未然形,ます,マセ,マセ ん 助動詞,*,*,*,不変化型,基本形,ん,ン,ン EOS
import CaboCha
cp = CaboCha.Parser("-r ./tools/usr/local/etc/cabocharc")
print(cp.parse("この泉質は極上です").toString(CaboCha.FORMAT_LATTICE))
print(cp.parse("この海鮮丼は美味しいです").toString(CaboCha.FORMAT_LATTICE))
print(cp.parse("近くにスカイツリーがあります").toString(CaboCha.FORMAT_LATTICE))
print(cp.parse("浴室にバスタオルがありません").toString(CaboCha.FORMAT_LATTICE))
* 0 1D 0/0 1.509856 この 連体詞,*,*,*,*,*,この,コノ,コノ * 1 2D 0/1 1.509856 泉質 名詞,一般,*,*,*,*,泉質,センシツ,センシツ,USER" は 助詞,係助詞,*,*,*,*,は,ハ,ワ * 2 -1D 0/1 0.000000 極上 名詞,一般,*,*,*,*,極上,ゴクジョウ,ゴクジョー です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス EOS * 0 1D 0/0 1.479074 この 連体詞,*,*,*,*,*,この,コノ,コノ * 1 2D 0/1 1.479074 海鮮丼 名詞,一般,*,*,*,*,海鮮丼,カイセンドン,カイセンドン,USER" は 助詞,係助詞,*,*,*,*,は,ハ,ワ * 2 -1D 0/1 0.000000 美味しい 形容詞,自立,*,*,形容詞・イ段,基本形,美味しい,オイシイ,オイシイ です 助動詞,*,*,*,特殊・デス,基本形,です,デス,デス EOS * 0 2D 0/1 -2.105621 近く 名詞,副詞可能,*,*,*,*,近く,チカク,チカク に 助詞,格助詞,一般,*,*,*,に,ニ,ニ * 1 2D 0/1 -2.105621 スカイツリー 名詞,一般,*,*,*,*,スカイツリー,スカイツリー,スカイツリー,USER" が 助詞,格助詞,一般,*,*,*,が,ガ,ガ * 2 -1D 0/1 0.000000 あり 動詞,自立,*,*,五段・ラ行,連用形,ある,アリ,アリ ます 助動詞,*,*,*,特殊・マス,基本形,ます,マス,マス EOS * 0 2D 0/1 -1.728522 浴室 名詞,一般,*,*,*,*,浴室,ヨクシツ,ヨクシツ に 助詞,格助詞,一般,*,*,*,に,ニ,ニ * 1 2D 0/1 -1.728522 バスタオル 名詞,一般,*,*,*,*,バスタオル,バスタオル,バスタオル,USER" が 助詞,格助詞,一般,*,*,*,が,ガ,ガ * 2 -1D 0/2 0.000000 あり 動詞,自立,*,*,五段・ラ行,連用形,ある,アリ,アリ ませ 助動詞,*,*,*,特殊・マス,未然形,ます,マセ,マセ ん 助動詞,*,*,*,不変化型,基本形,ん,ン,ン EOS
1. テキスト分析 (1)¶
1.0 事前準備 (定義済み関数の読み込み)¶
以下のセルを修正せずに実行してください
%load_ext autoreload
%autoreload 2
import os
import random
import numpy as np
# 再現性のために乱数を固定する
seed = 42
os.environ['PYTHONHASHSEED'] = str(seed)
np.random.seed(seed)
random.seed(seed)
# 定義済み関数をインポートする
import warnings
warnings.simplefilter('ignore')
import gssm_utils
1.1 データのダウンロード¶
以下のデータがダウンロード済みです
| ファイル名 | 件数 | データセット | 備考 |
|---|---|---|---|
| rakuten-1000-2024-2025.xlsx.zip | 10,000 | •レジャー+ビジネスの 10エリア •エリアごと 1,000件 (ランダムサンプリング) •期間: 2024/1~2025 GW明け |
本講義の全体を通して使用する |
# rakuten-1000-2024-2025.xlsx.zip をダウンロードする
FILE_ID = "1yKabZ7qJMRrIrP4Vtq-RrSZAqFsZriQS"
!gdown {FILE_ID}
!unzip -o rakuten-1000-2024-2025.xlsx.zip
Downloading... From: https://drive.google.com/uc?id=1yKabZ7qJMRrIrP4Vtq-RrSZAqFsZriQS To: /content/rakuten-1000-2024-2025.xlsx.zip 100% 2.61M/2.61M [00:00<00:00, 26.8MB/s] Archive: rakuten-1000-2024-2025.xlsx.zip inflating: rakuten-1000-2024-2025.xlsx
1.2 データの読み込み (DataFrame型)¶
import numpy as np
import pandas as pd
all_df = pd.read_excel("rakuten-1000-2024-2025.xlsx")
print(all_df.shape)
display(all_df.head())
(10000, 19)
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | A_レジャー | 01_登別 | 29995 | ゆとりろ洞爺湖 | わんこと泊まれて良かった! | 3 | 3 | 3 | 3 | 3.0 | 4.0 | 3.0 | レジャー | 家族 | 45413 | 投稿者 | na | na | 45445.668553 |
| 1 | A_レジャー | 01_登別 | 9691 | 登別温泉 ホテルゆもと登別 | 古い建物ですがきれいにしている感じでした。入った瞬間においが気になりましたが、タバコのにおい... | 5 | 5 | 5 | 4 | 5.0 | 4.0 | 5.0 | レジャー | 家族 | 45474 | mamemama3 | 40代 | 女性 | 45499.742442 |
| 2 | A_レジャー | 01_登別 | 40708 | 虎杖浜温泉 ホテル いずみ | 3月15日に初めて宿泊させて頂きました。予約プランは和室6畳でしたが、空きがあるとのことで1... | 5 | 5 | 5 | 5 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45717 | ハコ9437 | 40代 | 女性 | 45733.810486 |
| 3 | A_レジャー | 01_登別 | 139962 | ザ レイクビュー TOYA 乃の風リゾート | 大きめ柴犬と宿泊しましたが、部屋は充分な広さでした夕朝食のブッフェも、種類豊富で美味しかった... | 4 | 5 | 5 | 4 | 4.0 | 4.0 | 5.0 | レジャー | 家族 | 45413 | 投稿者 | na | na | 45440.662477 |
| 4 | A_レジャー | 01_登別 | 168374 | 虎杖浜天然温泉 「旅人の湯」ホテルルートインGrand室蘭 | コーヒー無料サービスが嬉しい。水のペットボトルサービスがあるとさらに良い(最近デフォルトのビ... | 4 | 3 | 4 | 4 | 3.0 | 3.0 | NaN | ビジネス | 一人 | 45505 | 投稿者 | na | na | 45529.484410 |
1.3 単語の抽出¶
コメント列から単語を抽出する (単語を品詞「名詞」「形容詞」「未知語」で絞り込む)
# 必要ライブラリのインポート
from collections import defaultdict
import MeCab
# mecab の初期化
tagger = MeCab.Tagger("-r ./tools/usr/local/etc/mecabrc --unk-feature 未知語")
# 単語頻度辞書の初期化
word_counts = defaultdict(lambda: 0)
# 抽出語情報リストの初期化
words = []
# 半角->全角変換マクロを定義する
ZEN = "".join(chr(0xff01 + i) for i in range(94))
HAN = "".join(chr(0x21 + i) for i in range(94))
HAN2ZEN = str.maketrans(HAN, ZEN)
# ストップワードを定義する
stopwords = ["する", "それ", "なる", "ない", "そこ", "これ" ,"ある"]
stopwords += ["湯畑"]
# データ1行ごとのループ
for index, row in all_df.iterrows():
# 半角->全角変換した後で, mecab で解析する
node = tagger.parseToNode(row["コメント"].translate(HAN2ZEN))
# 形態素ごとのループ
while node:
# 解析結果を要素ごとにバラす
features = node.feature.split(',')
# 品詞1 を取り出す
pos1 = features[0]
# 品詞2 を取り出す
pos2 = features[1] if len(features) > 1 else ""
# 原形 を取り出す
base = features[6] if len(features) > 6 else None
# 原型がストップワードに含まれない単語のみ抽出する
if base not in stopwords:
# 「名詞-一般」
if (pos1 == "名詞" and pos2 == "一般"):
base = base if base is not None else node.surface
postag = "名詞"
key = (base, postag)
# 単語頻度辞書をカウントアップする
word_counts[key] += 1
# 抽出語情報をリストに追加する
words.append([index + 1, base, postag, row["カテゴリー"], row["エリア"], key])
# 「形容動詞」
elif (pos1 == "名詞" and pos2 == "形容動詞語幹"):
base = base if base is not None else node.surface
base = f"{base}"
postag = "形容動詞"
key = (base, postag)
# 単語頻度辞書をカウントアップする
word_counts[key] += 1
# 抽出語情報をリストに追加する
words.append([index + 1, base, postag, row["カテゴリー"], row["エリア"], key])
# 「形容詞」
elif pos1 == "形容詞":
base = base if base is not None else node.surface
postag = "形容詞"
key = (base, postag)
# 単語頻度辞書をカウントアップする
word_counts[key] += 1
# 抽出語情報をリストに追加する
words.append([index + 1, base, postag, row["カテゴリー"], row["エリア"], key])
# 「未知語」
elif pos1 == "未知語":
base = base if base is not None else node.surface
postag = "未知語"
key = (base, postag)
# 単語頻度辞書をカウントアップする
word_counts[key] += 1
# 抽出語情報をリストに追加する
words.append([index + 1, base, postag, row["カテゴリー"], row["エリア"], key])
# 次の形態素へ
node = node.next
# DataFrme 型に整える
columns = [
"文書ID",
# "単語ID",
"表層",
"品詞",
"カテゴリー",
"エリア",
"dict_key",
]
docs_df = pd.DataFrame(words, columns=columns)
# DataFrame を表示する
print(docs_df.shape)
display(docs_df.head())
(149414, 6)
| 文書ID | 表層 | 品詞 | カテゴリー | エリア | dict_key | |
|---|---|---|---|---|---|---|
| 0 | 1 | わん | 名詞 | A_レジャー | 01_登別 | (わん, 名詞) |
| 1 | 1 | 良い | 形容詞 | A_レジャー | 01_登別 | (良い, 形容詞) |
| 2 | 2 | 古い | 形容詞 | A_レジャー | 01_登別 | (古い, 形容詞) |
| 3 | 2 | 建物 | 名詞 | A_レジャー | 01_登別 | (建物, 名詞) |
| 4 | 2 | きれい | 形容動詞 | A_レジャー | 01_登別 | (きれい, 形容動詞) |
抽出語の出現頻度をカウントする
# 「文書-抽出語」 表から単語の出現回数をカウントする
word_list = []
for i, (k, v) in enumerate(sorted(word_counts.items(), key=lambda x:x[1], reverse=True)):
word_list.append((i, k[0], v, k))
# DataFrame 型に整える
columns = [
"単語ID",
"表層",
"出現頻度",
"dict_key"
]
# DataFrame を表示する
word_counts_df = pd.DataFrame(word_list, columns=columns)
print(word_counts_df.shape)
display(word_counts_df.head(10))
(8745, 4)
| 単語ID | 表層 | 出現頻度 | dict_key | |
|---|---|---|---|---|
| 0 | 0 | 部屋 | 6363 | (部屋, 名詞) |
| 1 | 1 | 良い | 5242 | (良い, 形容詞) |
| 2 | 2 | ホテル | 2792 | (ホテル, 名詞) |
| 3 | 3 | 風呂 | 2688 | (風呂, 名詞) |
| 4 | 4 | 美味しい | 2290 | (美味しい, 形容詞) |
| 5 | 5 | 温泉 | 1836 | (温泉, 名詞) |
| 6 | 6 | スタッフ | 1623 | (スタッフ, 名詞) |
| 7 | 7 | 立地 | 1434 | (立地, 名詞) |
| 8 | 8 | よい | 1411 | (よい, 形容詞) |
| 9 | 9 | 広い | 1387 | (広い, 形容詞) |
単語IDを紐つける (出現回数 Top 150語のみ抽出する)
# 「単語出現回数」 表から出現回数Top 150語のみ抽出する
word_counts_150_df = word_counts_df[0:150]
# 「文書-抽出語」 表も出現回数Top 150語のみに絞り込む
merged_df = pd.merge(docs_df, word_counts_150_df, how="inner", on="dict_key", suffixes=["", "_right"])
docs_150_df = merged_df[["文書ID", "単語ID", "表層", "品詞", "カテゴリー", "エリア", "dict_key"]]
# DataFrame を表示する
print(docs_150_df.shape)
display(docs_150_df)
(82201, 7)
| 文書ID | 単語ID | 表層 | 品詞 | カテゴリー | エリア | dict_key | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 1 | 良い | 形容詞 | A_レジャー | 01_登別 | (良い, 形容詞) |
| 1 | 2 | 38 | 古い | 形容詞 | A_レジャー | 01_登別 | (古い, 形容詞) |
| 2 | 2 | 74 | 建物 | 名詞 | A_レジャー | 01_登別 | (建物, 名詞) |
| 3 | 2 | 58 | きれい | 形容動詞 | A_レジャー | 01_登別 | (きれい, 形容動詞) |
| 4 | 2 | 26 | 感じ | 名詞 | A_レジャー | 01_登別 | (感じ, 名詞) |
| ... | ... | ... | ... | ... | ... | ... | ... |
| 82196 | 10000 | 24 | 気 | 名詞 | B_ビジネス | 10_福岡 | (気, 名詞) |
| 82197 | 10000 | 3 | 風呂 | 名詞 | B_ビジネス | 10_福岡 | (風呂, 名詞) |
| 82198 | 10000 | 0 | 部屋 | 名詞 | B_ビジネス | 10_福岡 | (部屋, 名詞) |
| 82199 | 10000 | 39 | 人 | 名詞 | B_ビジネス | 10_福岡 | (人, 名詞) |
| 82200 | 10000 | 39 | 人 | 名詞 | B_ビジネス | 10_福岡 | (人, 名詞) |
82201 rows × 7 columns
1.5 ワードクラウド¶
# 出現回数Top 75単語でワードクラウドを作成する
words = ' '.join(word_counts_df['表層'][0:75])
gssm_utils.plot_wordcloud(words)
1.6 「文書-抽出語」表の作成¶
「文書-抽出語」表を作成する (出現回数 Top 75語)
# 「単語出現回数」 表から出現回数Top 75語のみ抽出する
word_counts_75_df = word_counts_df[0:75]
# 「文書-抽出語」 表も出現回数Top 75語のみに絞り込む
merged_df = pd.merge(docs_df, word_counts_75_df, how="inner", on="dict_key", suffixes=["", "_right"])
docs_75_df = merged_df[["文書ID", "単語ID", "表層", "品詞", "カテゴリー", "エリア", "dict_key"]]
# 「カテゴリー,エリア」でクロス集計する
cross_75_df = pd.crosstab(
[
docs_75_df['カテゴリー'],
docs_75_df['エリア'],
docs_75_df['文書ID']
],
docs_75_df['単語ID'], margins=False
)
cross_75_df.columns = word_counts_75_df["表層"]
# DataFrame を表示する
print(cross_75_df.shape)
display(cross_75_df)
(9601, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| カテゴリー | エリア | 文書ID | |||||||||||||||||||||
| A_レジャー | 01_登別 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 3 | 1 | 4 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 4 | 2 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | ||
| 5 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| B_ビジネス | 10_福岡 | 9996 | 0 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 3 | 0 | 1 |
| 9997 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| 9998 | 1 | 1 | 0 | 0 | 0 | 0 | 3 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 9999 | 1 | 1 | 1 | 2 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| 10000 | 2 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
9601 rows × 75 columns
「文書-抽出語」 表を {0,1} に変換する
# 「文書-抽出語」 表を {0,1} に変換する
cross_75_df[cross_75_df > 0] = 1
# DataFrame を表示する
print(cross_75_df.shape)
display(cross_75_df)
(9601, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| カテゴリー | エリア | 文書ID | |||||||||||||||||||||
| A_レジャー | 01_登別 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 3 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 4 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | ||
| 5 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| B_ビジネス | 10_福岡 | 9996 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| 9997 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| 9998 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 9999 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| 10000 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
9601 rows × 75 columns
1.7 共起ネットワーク図¶
1.7.1 共起度行列を作成する (抽出語-抽出語)¶
# 必要ライブラリのインポート
from scipy.sparse import csc_matrix
# 共起行列を作成する
X = cross_75_df.values
X = csc_matrix(X)
Xc = (X.T * X)
# 対角成分のみにする
Xc = np.triu(Xc.toarray())
# DataFrame 型に整える
cooccur_75_df = pd.DataFrame(Xc, columns=cross_75_df.columns, index=cross_75_df.columns)
# DataFrame を表示する
print(cooccur_75_df.shape)
display(cooccur_75_df.head())
(75, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 表層 | |||||||||||||||||||||
| 部屋 | 4390 | 1877 | 1032 | 1267 | 1055 | 708 | 777 | 666 | 655 | 973 | ... | 170 | 179 | 187 | 145 | 175 | 151 | 159 | 176 | 213 | 190 |
| 良い | 0 | 3703 | 873 | 1000 | 889 | 682 | 694 | 758 | 329 | 573 | ... | 160 | 116 | 139 | 138 | 115 | 126 | 120 | 122 | 123 | 147 |
| ホテル | 0 | 0 | 1996 | 438 | 380 | 277 | 358 | 353 | 257 | 310 | ... | 109 | 81 | 94 | 88 | 69 | 87 | 98 | 68 | 87 | 71 |
| 風呂 | 0 | 0 | 0 | 2142 | 634 | 366 | 363 | 301 | 344 | 445 | ... | 86 | 84 | 103 | 80 | 90 | 67 | 54 | 96 | 94 | 99 |
| 美味しい | 0 | 0 | 0 | 0 | 2023 | 469 | 420 | 247 | 281 | 341 | ... | 76 | 67 | 107 | 60 | 113 | 43 | 43 | 59 | 50 | 70 |
5 rows × 75 columns
1.7.2 Jaccard 係数を求める (抽出語-抽出語)¶
# 共起行列の中身を Jaccard 係数に入れ替える
jaccard_75_df = gssm_utils.jaccard_coef(cooccur_75_df, cross_75_df)
# DataFrame を表示する
print(jaccard_75_df.shape)
display(jaccard_75_df.head())
(75, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 表層 | |||||||||||||||||||||
| 部屋 | 0.0 | 0.301963 | 0.192753 | 0.240646 | 0.196902 | 0.139315 | 0.155899 | 0.130129 | 0.132914 | 0.208798 | ... | 0.037437 | 0.039514 | 0.041445 | 0.031924 | 0.038751 | 0.033238 | 0.035365 | 0.039224 | 0.047523 | 0.042175 |
| 良い | 0.0 | 0.000000 | 0.180895 | 0.206398 | 0.183792 | 0.154264 | 0.158447 | 0.174695 | 0.072039 | 0.131031 | ... | 0.041408 | 0.029698 | 0.035889 | 0.035733 | 0.029571 | 0.032466 | 0.031185 | 0.031655 | 0.031660 | 0.038073 |
| ホテル | 0.0 | 0.000000 | 0.000000 | 0.118378 | 0.104424 | 0.088811 | 0.118976 | 0.116233 | 0.087653 | 0.105838 | ... | 0.049366 | 0.036258 | 0.042515 | 0.039909 | 0.030969 | 0.039313 | 0.045307 | 0.030895 | 0.039295 | 0.031839 |
| 風呂 | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.179553 | 0.115239 | 0.115238 | 0.093045 | 0.115012 | 0.151361 | ... | 0.036180 | 0.035339 | 0.043867 | 0.033913 | 0.038249 | 0.028163 | 0.022949 | 0.041397 | 0.039949 | 0.042164 |
| 美味しい | 0.0 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.158768 | 0.141224 | 0.077918 | 0.095741 | 0.116581 | ... | 0.033510 | 0.029451 | 0.048090 | 0.026549 | 0.051108 | 0.018827 | 0.019154 | 0.026375 | 0.021949 | 0.031001 |
5 rows × 75 columns
1.7.3 プロットする¶
# 抽出語の出現回数(ノードの大きさ)を取得する
word_counts = cross_75_df.sum(axis=0).values
# 共起行列(Jaccard係数)で共起ネットワーク図を作成する
gssm_utils.plot_cooccur_network(jaccard_75_df, word_counts, np.sort(jaccard_75_df.values.reshape(-1))[::-1][60])
<Figure size 800x800 with 0 Axes>
1.8 係り受けネットワーク図¶
1.8.1 係り受け行列を作成する¶
# チャンク(文節)から単語を取り出す
def get_words(tree, from_chunk, stopwords):
# チャンク(文節)の開始位置を取得する
beg = from_chunk.token_pos
# チャンクの開始位置を取得する
end = from_chunk.token_pos + from_chunk.token_size
# 抽出語情報リストの初期化
words = []
# チャンク(文節)ごとのループ
for i in range(beg, end):
# チャンク中の形態素を取り出す
token = tree.token(i)
# 解析結果を要素ごとにバラす
features = token.feature.split(',')
# 品詞1 を取り出す
pos1 = features[0]
# 品詞2 を取り出す
pos2 = features[1] if len(features) > 1 else ""
# 原形 を取り出す
base = features[6] if len(features) > 6 else None
# 原型がストップワードに含まれない単語のみ抽出する
if base not in stopwords:
# 「名詞-一般」
if (pos1 == "名詞" and pos2 == "一般"):
base = base if base is not None else node.surface
postag = "名詞"
key = (base, postag)
# 抽出語情報をリストに追加する
words.append(key)
# 「形容動詞」
elif (pos1 == "名詞" and pos2 == "形容動詞語幹"):
base = base if base is not None else node.surface
base = f"{base}だ"
postag = "形容動詞"
key = (base, postag)
# 抽出語情報をリストに追加する
words.append(key)
# 「形容詞」
elif pos1 == "形容詞":
base = base if base is not None else node.surface
postag = "形容詞"
key = (base, postag)
# 抽出語情報をリストに追加する
words.append(key)
# 「未知語」
elif pos1 == "未知語":
base = base if base is not None else node.surface
postag = "未知語"
key = (base, postag)
# 抽出語情報をリストに追加する
words.append(key)
# 抽出語情報をリストを返却する
return words
# 必要ライブラリのインポート
import CaboCha
# cabocha の初期化
cp = CaboCha.Parser("-r ./tools/usr/local/etc/cabocharc")
# 半角->全角変換マクロを定義する
ZEN = "".join(chr(0xff01 + i) for i in range(94))
HAN = "".join(chr(0x21 + i) for i in range(94))
HAN2ZEN = str.maketrans(HAN, ZEN)
# ストップワードを定義する
stopwords = ["する", "それ", "なる", "ない", "そこ", "これ" ,"ある"]
stopwords += ["湯畑"]
stopwords += ['*'] # 原形に 「'*'」 が出力された場合に除去するため
# 係り受けペア辞書の初期化
pair_counts = defaultdict(lambda: 0)
pairs = []
# データ1行ごとのループ
for index, row in all_df.iterrows():
# 半角->全角変換した後で, cabocha で解析する
tree = cp.parse(row["コメント"].translate(HAN2ZEN))
# 解析結果から空でないチャンク(文節)のリストを集める
chunks = {}
key = 0
for i in range(tree.size()):
tok = tree.token(i)
if tok.chunk:
chunks[key] = tok.chunk
key += 1
# 係り元と係り先の単語情報(原形と品詞)を集める
from_words, to_words = [], []
for from_chunk in chunks.values():
# 係り先がなければスキップ
if from_chunk.link < 0:
continue
# 係り先のチャンク(文節)を取得する
to_chunk = chunks[from_chunk.link]
# 係り元の単語情報(原形と品詞)を取得する
from_words = get_words(tree, from_chunk, stopwords)
# 係り先の単語情報(原形と品詞)を取得する
to_words = get_words(tree, to_chunk, stopwords)
# 係り受けペアと頻度を収集する
for f in from_words:
for t in to_words:
key = (f[0], t[0])
pair_counts[key] += 1
# 係り受け行列を初期化する (共起行列と同じ形)
Xd = np.zeros(cooccur_75_df.shape)
# 係り受けペアを係り受け列に変換する
for (f,t), v in pair_counts.items():
columns = list(cooccur_75_df.columns)
if f in columns and t in columns:
i = columns.index(f)
j = columns.index(t)
Xd[i,j] = v
# DataFrme 型に整える
dep_75_df = pd.DataFrame(Xd, columns=cooccur_75_df.columns, index=cooccur_75_df.columns)
print(dep_75_df.shape)
display(dep_75_df.head())
(75, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 表層 | |||||||||||||||||||||
| 部屋 | 0.0 | 9.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 2.0 | 3.0 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 良い | 1.0 | 2.0 | 27.0 | 0.0 | 0.0 | 1.0 | 0.0 | 2.0 | 0.0 | 1.0 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| ホテル | 0.0 | 0.0 | 0.0 | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.0 | 1.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 風呂 | 0.0 | 15.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 5.0 | 0.0 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 美味しい | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | ... | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
5 rows × 75 columns
1.8.2 条件付き確率を求める¶
# 係り受け行列の中身(numpy行列)を取り出す
Xc = dep_75_df.values
# 係り受け行列(条件付き確率)を初期化する (元の係り受け行列と同じ形)
Xd = np.zeros(Xc.shape)
# 係り元単語の出現頻度を取得する
word_counts = cooccur_75_df.sum(axis=0).values
# 係り受けペアごとのループ
for (f,t), v in pair_counts.items():
columns = list(dep_75_df.columns)
# 係り元と係り先の両方が列に含まれる
if f in columns and t in columns:
i = columns.index(f)
j = columns.index(t)
# 条件付き確率(係り受け頻度/係り先出現回数)を求める
Xd[i,j] = v / word_counts[i]
# DataFrame 型に整える
dep_75_df = pd.DataFrame(Xd, columns=dep_75_df.columns, index=dep_75_df.columns)
# DataFrame を表示する
print(dep_75_df.shape)
display(dep_75_df.head())
(75, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 表層 | |||||||||||||||||||||
| 部屋 | 0.000000 | 0.002050 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.0 | 0.000000 | 0.000456 | 0.000683 | ... | 0.0 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 良い | 0.000179 | 0.000358 | 0.004839 | 0.0 | 0.000000 | 0.000179 | 0.0 | 0.000358 | 0.000000 | 0.000179 | ... | 0.0 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| ホテル | 0.000000 | 0.000000 | 0.000000 | 0.0 | 0.000256 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | ... | 0.0 | 0.000256 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 風呂 | 0.000000 | 0.003095 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.0 | 0.000000 | 0.001032 | 0.000000 | ... | 0.0 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
| 美味しい | 0.000000 | 0.000000 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.0 | 0.000000 | 0.000000 | 0.000000 | ... | 0.0 | 0.000000 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 | 0.0 |
5 rows × 75 columns
1.8.3 プロットする¶
# 抽出語の出現回数(ノードの大きさ)を取得する
word_counts = cross_75_df.sum(axis=0).values
# 係り受け(条件付き確率)で共起ネットワーク図を作成する
gssm_utils.plot_dependency_network(dep_75_df, word_counts, np.sort(dep_75_df.values.reshape(-1))[::-1][60], pyvis=True)
pyvis.html
<Figure size 800x800 with 0 Axes>
1.9 対応分析¶
「文書-抽出語」 表を確認する
# DataFrame を表示する
print(cross_75_df.shape)
display(cross_75_df.head())
(9601, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| カテゴリー | エリア | 文書ID | |||||||||||||||||||||
| A_レジャー | 01_登別 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 3 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 4 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | ||
| 5 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
5 rows × 75 columns
1.9.1 「外部変数-抽出語」 クロス集計表を作成する¶
# 「カテゴリー」のクロス集計と「エリア」のクロス集計を連結する
aggregate_75_df = pd.concat(
[
cross_75_df.groupby(level='カテゴリー').sum(),
cross_75_df.groupby(level='エリア').sum()
]
)
# DataFrame を表示する
print(aggregate_75_df.shape)
display(aggregate_75_df)
(12, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| A_レジャー | 2325 | 2054 | 753 | 1474 | 1504 | 1292 | 856 | 550 | 648 | 676 | ... | 141 | 149 | 185 | 152 | 235 | 110 | 71 | 128 | 145 | 208 |
| B_ビジネス | 2065 | 1649 | 1243 | 668 | 519 | 108 | 515 | 844 | 545 | 567 | ... | 180 | 170 | 124 | 145 | 66 | 194 | 194 | 145 | 160 | 97 |
| 01_登別 | 435 | 398 | 157 | 301 | 269 | 267 | 118 | 57 | 109 | 142 | ... | 15 | 32 | 36 | 26 | 41 | 16 | 19 | 28 | 27 | 29 |
| 02_草津 | 481 | 441 | 168 | 362 | 289 | 287 | 193 | 161 | 141 | 130 | ... | 51 | 24 | 39 | 22 | 49 | 26 | 11 | 31 | 29 | 70 |
| 03_箱根 | 510 | 450 | 166 | 287 | 351 | 220 | 195 | 57 | 142 | 144 | ... | 24 | 32 | 43 | 38 | 52 | 15 | 20 | 28 | 26 | 40 |
| 04_道後 | 380 | 366 | 218 | 190 | 202 | 257 | 103 | 164 | 136 | 113 | ... | 22 | 30 | 27 | 29 | 28 | 38 | 15 | 17 | 30 | 30 |
| 05_湯布院 | 519 | 399 | 44 | 334 | 393 | 261 | 247 | 111 | 120 | 147 | ... | 29 | 31 | 40 | 37 | 65 | 15 | 6 | 24 | 33 | 39 |
| 06_札幌 | 399 | 324 | 263 | 118 | 145 | 27 | 102 | 170 | 105 | 125 | ... | 35 | 38 | 18 | 22 | 21 | 33 | 37 | 21 | 24 | 20 |
| 07_名古屋 | 388 | 334 | 243 | 147 | 95 | 26 | 125 | 145 | 115 | 106 | ... | 33 | 33 | 34 | 34 | 11 | 36 | 38 | 30 | 34 | 23 |
| 08_東京 | 416 | 333 | 224 | 133 | 80 | 15 | 99 | 170 | 96 | 86 | ... | 32 | 35 | 19 | 34 | 9 | 39 | 39 | 29 | 38 | 15 |
| 09_大阪 | 423 | 305 | 252 | 126 | 88 | 19 | 96 | 171 | 118 | 132 | ... | 34 | 34 | 22 | 34 | 16 | 42 | 42 | 38 | 34 | 11 |
| 10_福岡 | 439 | 353 | 261 | 144 | 111 | 21 | 93 | 188 | 111 | 118 | ... | 46 | 30 | 31 | 21 | 9 | 44 | 38 | 27 | 30 | 28 |
12 rows × 75 columns
1.9.2 対応分析プロットを作成する¶
# 必要ライブラリのインポート
import mca
# ライブラリ mca による対応分析
ncols = aggregate_75_df.shape[1]
mca_ben = mca.MCA(aggregate_75_df, ncols=ncols, benzecri=False)
# 行方向および列方向の値を取り出す
row_coord = mca_ben.fs_r(N=2)
col_coord = mca_ben.fs_c(N=2)
# 固有値を求める
eigenvalues = mca_ben.L
total = np.sum(eigenvalues)
# 寄与率を求める
explained_inertia = 100 * eigenvalues / total
# 行方向および列方向のラベルを取得する
row_labels = aggregate_75_df.index
col_labels = aggregate_75_df.columns
# プロットする
gssm_utils.plot_coresp(row_coord, col_coord, row_labels, col_labels, explained_inertia)
1.10 トピックモデル¶
「文書-抽出語」 表を確認する
# DataFrame を表示する
print(cross_75_df.shape)
display(cross_75_df.head())
(9601, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| カテゴリー | エリア | 文書ID | |||||||||||||||||||||
| A_レジャー | 01_登別 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 3 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 4 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | ||
| 5 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 |
5 rows × 75 columns
1.10.1 トピックを抽出する (LDA)¶
# 必要ライブラリのインポート
from sklearn.decomposition import LatentDirichletAllocation as LDA
# ライブラリ LDA によるトピック抽出
lda = LDA(max_iter=25, learning_method='batch', random_state=42, n_jobs=-1, n_components=6)
lda.fit(cross_75_df.values)
# トピックごとに出現確率Top 20語を表示する
n_top_words = 20
feature_names = cross_75_df.columns
for topic_idx, topic in enumerate(lda.components_):
print(f"Topic # {topic_idx+1}:", end=" ")
for i in topic.argsort()[:-n_top_words-1:-1]:
print(feature_names[i], end=" ")
print()
Topic # 1: 温泉 良い 宿 美味しい 部屋 露天風呂 風呂 スタッフ 夕食 素晴らしい 大変 最高 湯 楽しい 気持ちよい 素敵 建物 浴場 お湯 丁寧 Topic # 2: 便利 駅 近い 立地 コンビニ 良い ホテル 徒歩 よい 場所 部屋 安い やすい 値段 静か 大変 アメニティ 多い 無料 ありがたい Topic # 3: 良い 綺麗 部屋 風呂 立地 ホテル やすい 古い 無い 水 高い 残念 トイレ 美味しい 感じ 狭い アメニティ 悪い 安い フロント Topic # 4: ホテル スタッフ フロント 部屋 嬉しい 良い 丁寧 いい 人 アウト 親切 他 女性 感じ 荷物 悪い 多い よい 大変 気 Topic # 5: 部屋 広い 快適 清潔 良い 浴場 ベッド きれい 風呂 ホテル トイレ 十分 狭い ルーム 気 バス よい アメニティ 非常 残念 Topic # 6: 美味しい 風呂 最高 よい 部屋 種類 バイキング 家族 広い おいしい 子供 多い ご飯 残念 夕食 少ない 大変 露天風呂 無料 いい
ChatGPT を使ってトピックを説明する
プロンプトの例:
以下はトピックとトピックごとの高確率ワードです. これを読んで各トピックを簡潔に要約してください.
Topic # 1 フロント ホテル 浴場 部屋 親切だ 良い …
結果の例:
- Topic #1: 温泉・宿泊体験の満足感
- Topic #2: 立地の便利さとコスパ
- Topic #3: コスパと施設の状態
- Topic #4: スタッフ対応と接客態度
- Topic #5: 客室の広さと快適さ
- Topic #6: 食事と家族向けサービスの充実
1.10.2 トピックをワードクラウドで描画する¶
# トピックごとに出現確率Top 75語でワードクラウドを作成する
n_top_words = 75
gssm_utils.plot_topic_model(lda, feature_names, n_top_words)
1.10.3 トピック分布をプロットする¶
# 文書ごとのトピック比率を取得
doc_topic_distributions = lda.transform(cross_75_df.values)
# 文書全体のトピック比率を計算(平均を取る)
overall_topic_distribution = np.mean(doc_topic_distributions, axis=0)
gssm_utils.plot_topic_distribution(overall_topic_distribution)
1.11 外部変数の利用¶
1.11.1 「文書-抽出語」表の確認¶
「文書-抽出語」表を確認する (出現回数 Top 75語, {0,1} に変換済み)
# DataFrame を表示する
print(cross_75_df.shape)
display(cross_75_df)
(9601, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 | ||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| カテゴリー | エリア | 文書ID | |||||||||||||||||||||
| A_レジャー | 01_登別 | 1 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
| 2 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 3 | 1 | 1 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 4 | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 1 | ... | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | ||
| 5 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ||
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| B_ビジネス | 10_福岡 | 9996 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 1 |
| 9997 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| 9998 | 1 | 1 | 0 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 1 | ||
| 9999 | 1 | 1 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | ||
| 10000 | 1 | 0 | 1 | 1 | 0 | 0 | 0 | 0 | 0 | 0 | ... | 1 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 | 0 |
9601 rows × 75 columns
1.11.1 共起行列を作成する (外部変数-抽出語)¶
# 「カテゴリー」のクロス集計と「エリア」のクロス集計を連結する
aggregate_df = pd.concat(
[
cross_75_df.groupby(level='カテゴリー').sum(),
cross_75_df.groupby(level='エリア').sum()
]
)
# DataFrame を表示する
print(aggregate_df.shape)
display(aggregate_df)
(12, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| A_レジャー | 2325 | 2054 | 753 | 1474 | 1504 | 1292 | 856 | 550 | 648 | 676 | ... | 141 | 149 | 185 | 152 | 235 | 110 | 71 | 128 | 145 | 208 |
| B_ビジネス | 2065 | 1649 | 1243 | 668 | 519 | 108 | 515 | 844 | 545 | 567 | ... | 180 | 170 | 124 | 145 | 66 | 194 | 194 | 145 | 160 | 97 |
| 01_登別 | 435 | 398 | 157 | 301 | 269 | 267 | 118 | 57 | 109 | 142 | ... | 15 | 32 | 36 | 26 | 41 | 16 | 19 | 28 | 27 | 29 |
| 02_草津 | 481 | 441 | 168 | 362 | 289 | 287 | 193 | 161 | 141 | 130 | ... | 51 | 24 | 39 | 22 | 49 | 26 | 11 | 31 | 29 | 70 |
| 03_箱根 | 510 | 450 | 166 | 287 | 351 | 220 | 195 | 57 | 142 | 144 | ... | 24 | 32 | 43 | 38 | 52 | 15 | 20 | 28 | 26 | 40 |
| 04_道後 | 380 | 366 | 218 | 190 | 202 | 257 | 103 | 164 | 136 | 113 | ... | 22 | 30 | 27 | 29 | 28 | 38 | 15 | 17 | 30 | 30 |
| 05_湯布院 | 519 | 399 | 44 | 334 | 393 | 261 | 247 | 111 | 120 | 147 | ... | 29 | 31 | 40 | 37 | 65 | 15 | 6 | 24 | 33 | 39 |
| 06_札幌 | 399 | 324 | 263 | 118 | 145 | 27 | 102 | 170 | 105 | 125 | ... | 35 | 38 | 18 | 22 | 21 | 33 | 37 | 21 | 24 | 20 |
| 07_名古屋 | 388 | 334 | 243 | 147 | 95 | 26 | 125 | 145 | 115 | 106 | ... | 33 | 33 | 34 | 34 | 11 | 36 | 38 | 30 | 34 | 23 |
| 08_東京 | 416 | 333 | 224 | 133 | 80 | 15 | 99 | 170 | 96 | 86 | ... | 32 | 35 | 19 | 34 | 9 | 39 | 39 | 29 | 38 | 15 |
| 09_大阪 | 423 | 305 | 252 | 126 | 88 | 19 | 96 | 171 | 118 | 132 | ... | 34 | 34 | 22 | 34 | 16 | 42 | 42 | 38 | 34 | 11 |
| 10_福岡 | 439 | 353 | 261 | 144 | 111 | 21 | 93 | 188 | 111 | 118 | ... | 46 | 30 | 31 | 21 | 9 | 44 | 38 | 27 | 30 | 28 |
12 rows × 75 columns
1.11.2 Jaccard 係数を求める (外部変数-抽出語)¶
# 抽出語の出現回数を取得する
word_counts = cross_75_df.sum(axis=0).values
# 属性(外部変数)出現数を取得する
attr_counts = np.hstack(
[
all_df.value_counts('カテゴリー').values,
all_df.value_counts('エリア').values
]
)
# 共起行列の中身を Jaccard 係数に入れ替える
jaccard_attrs_df = gssm_utils.jaccard_attrs_coef(aggregate_df, attr_counts, word_counts, total=10000, conditional=False)
# DataFrame を表示する
print(jaccard_attrs_df.shape)
display(jaccard_attrs_df)
(12, 75)
| 表層 | 部屋 | 良い | ホテル | 風呂 | 美味しい | 温泉 | スタッフ | 立地 | よい | 広い | ... | 徒歩 | ありがたい | 少ない | 女性 | 楽しい | 安い | ルーム | 水 | 十分 | 建物 |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| A_レジャー | 0.329087 | 0.308919 | 0.000000 | 0.260056 | 0.272513 | 0.252937 | 0.155213 | 0.000000 | 0.116862 | 0.121430 | ... | 0.000000 | 0.000000 | 0.036105 | 0.029543 | 0.046388 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.040808 |
| B_ビジネス | 0.000000 | 0.000000 | 0.216061 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.152072 | 0.000000 | 0.000000 | ... | 0.035013 | 0.033016 | 0.000000 | 0.000000 | 0.000000 | 0.037965 | 0.038257 | 0.028276 | 0.031098 | 0.000000 |
| 01_登別 | 0.000000 | 0.092451 | 0.000000 | 0.105949 | 0.097676 | 0.125176 | 0.000000 | 0.000000 | 0.000000 | 0.067587 | ... | 0.000000 | 0.024864 | 0.028280 | 0.000000 | 0.032540 | 0.000000 | 0.000000 | 0.022490 | 0.000000 | 0.000000 |
| 02_草津 | 0.097983 | 0.103473 | 0.000000 | 0.130216 | 0.105706 | 0.135826 | 0.088613 | 0.072100 | 0.068713 | 0.061524 | ... | 0.040157 | 0.000000 | 0.030709 | 0.000000 | 0.039137 | 0.000000 | 0.000000 | 0.024960 | 0.000000 | 0.056680 |
| 03_箱根 | 0.104508 | 0.105808 | 0.000000 | 0.100525 | 0.131362 | 0.100917 | 0.089614 | 0.000000 | 0.069235 | 0.068604 | ... | 0.000000 | 0.024864 | 0.033965 | 0.030183 | 0.041633 | 0.000000 | 0.000000 | 0.022490 | 0.000000 | 0.031621 |
| 04_道後 | 0.000000 | 0.000000 | 0.078474 | 0.000000 | 0.000000 | 0.119925 | 0.000000 | 0.073543 | 0.066116 | 0.000000 | ... | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.030016 | 0.000000 | 0.000000 | 0.000000 | 0.000000 |
| 05_湯布院 | 0.106549 | 0.092704 | 0.000000 | 0.118946 | 0.149430 | 0.122020 | 0.116290 | 0.000000 | 0.057887 | 0.070134 | ... | 0.000000 | 0.000000 | 0.031521 | 0.029365 | 0.052589 | 0.000000 | 0.000000 | 0.000000 | 0.025943 | 0.030806 |
| 06_札幌 | 0.000000 | 0.000000 | 0.096231 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.076439 | 0.000000 | 0.059018 | ... | 0.027216 | 0.029664 | 0.000000 | 0.000000 | 0.000000 | 0.025964 | 0.030130 | 0.000000 | 0.000000 | 0.000000 |
| 07_名古屋 | 0.000000 | 0.000000 | 0.088267 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.064473 | 0.000000 | 0.000000 | ... | 0.025621 | 0.025661 | 0.026667 | 0.026920 | 0.000000 | 0.028391 | 0.030970 | 0.024135 | 0.026751 | 0.000000 |
| 08_東京 | 0.000000 | 0.000000 | 0.080808 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.076439 | 0.000000 | 0.000000 | ... | 0.000000 | 0.027259 | 0.000000 | 0.026920 | 0.000000 | 0.030830 | 0.031811 | 0.023312 | 0.029992 | 0.000000 |
| 09_大阪 | 0.000000 | 0.000000 | 0.091837 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.076923 | 0.000000 | 0.062530 | ... | 0.026418 | 0.026459 | 0.000000 | 0.026920 | 0.000000 | 0.033281 | 0.034342 | 0.030769 | 0.026751 | 0.000000 |
| 10_福岡 | 0.000000 | 0.000000 | 0.095430 | 0.000000 | 0.000000 | 0.000000 | 0.000000 | 0.085222 | 0.000000 | 0.000000 | ... | 0.036078 | 0.000000 | 0.024257 | 0.000000 | 0.000000 | 0.034921 | 0.030970 | 0.000000 | 0.000000 | 0.000000 |
12 rows × 75 columns
1.11.4 特徴語ランキング¶
# 「カテゴリ」や「エリア」ごとに Jaccard 係数のTop 10語を抽出する
df_list = []
for index, row in jaccard_attrs_df.iterrows():
df_list.append(row.iloc[np.argsort(row.values)[::-1][:10]].reset_index())
# 「カテゴリ」や「エリア」ごとの Jaccard 係数のTop 10 を横方向に連結した DetaFrame を作成する
ranking_df = pd.DataFrame(pd.concat(df_list, axis=1))
ranking_df.columns = np.array([c for pair in [[x,f"jaccard"] for x in jaccard_attrs_df.index] for c in pair], dtype='object')
# DataFrame を表示する
display(ranking_df)
| A_レジャー | jaccard | B_ビジネス | jaccard | 01_登別 | jaccard | 02_草津 | jaccard | 03_箱根 | jaccard | ... | 06_札幌 | jaccard | 07_名古屋 | jaccard | 08_東京 | jaccard | 09_大阪 | jaccard | 10_福岡 | jaccard | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 部屋 | 0.329087 | ホテル | 0.216061 | 温泉 | 0.125176 | 温泉 | 0.135826 | 露天風呂 | 0.137092 | ... | ホテル | 0.096231 | ホテル | 0.088267 | 駅 | 0.122837 | 駅 | 0.099379 | ホテル | 0.095430 |
| 1 | 良い | 0.308919 | 駅 | 0.152966 | 風呂 | 0.105949 | 風呂 | 0.130216 | 美味しい | 0.131362 | ... | 便利 | 0.083069 | 駅 | 0.070368 | 近い | 0.082988 | ホテル | 0.091837 | 立地 | 0.085222 |
| 2 | 美味しい | 0.272513 | 立地 | 0.152072 | 美味しい | 0.097676 | 宿 | 0.111179 | 良い | 0.105808 | ... | 立地 | 0.076439 | 便利 | 0.069488 | 便利 | 0.081924 | 便利 | 0.080211 | 便利 | 0.082496 |
| 3 | 風呂 | 0.260056 | 便利 | 0.142236 | 良い | 0.092451 | 美味しい | 0.105706 | 部屋 | 0.104508 | ... | 浴場 | 0.070343 | 立地 | 0.064473 | コンビニ | 0.081323 | 立地 | 0.076923 | 駅 | 0.080466 |
| 4 | 温泉 | 0.252937 | 近い | 0.107584 | 夕食 | 0.085120 | 良い | 0.103473 | 温泉 | 0.100917 | ... | 駅 | 0.069780 | フロント | 0.063806 | ホテル | 0.080808 | 近い | 0.074706 | 近い | 0.065928 |
| 5 | スタッフ | 0.155213 | フロント | 0.104562 | 残念 | 0.080441 | 部屋 | 0.097983 | 風呂 | 0.100525 | ... | 快適 | 0.062574 | アメニティ | 0.061292 | 立地 | 0.076439 | コンビニ | 0.068801 | フロント | 0.065611 |
| 6 | 宿 | 0.147732 | 綺麗 | 0.102536 | 種類 | 0.080087 | スタッフ | 0.088613 | 夕食 | 0.097240 | ... | 綺麗 | 0.061578 | 綺麗 | 0.059421 | フロント | 0.061408 | フロント | 0.065008 | 快適 | 0.055718 |
| 7 | 露天風呂 | 0.144698 | 快適 | 0.093102 | 多い | 0.074556 | 湯 | 0.086039 | 宿 | 0.091182 | ... | 広い | 0.059018 | 快適 | 0.055100 | アメニティ | 0.056366 | 快適 | 0.062574 | コンビニ | 0.050904 |
| 8 | 最高 | 0.131296 | コンビニ | 0.087271 | 露天風呂 | 0.073805 | 最高 | 0.084148 | スタッフ | 0.089614 | ... | フロント | 0.058427 | 近い | 0.054850 | 快適 | 0.054482 | 広い | 0.062530 | アメニティ | 0.050792 |
| 9 | 夕食 | 0.122550 | アメニティ | 0.073719 | 最高 | 0.070777 | バス | 0.080908 | 大変 | 0.085714 | ... | コンビニ | 0.054435 | コンビニ | 0.047397 | やすい | 0.051525 | 綺麗 | 0.059421 | ベッド | 0.044886 |
10 rows × 24 columns
1.11.5 ワードクラウド (カテゴリーごと)¶
for name, group in cross_75_df.groupby(level='カテゴリー'):
print(name)
# 「カテゴリー」ごとに Jaccard 係数でソートする
sorted_columns = np.argsort(jaccard_attrs_df.loc[name].values)[::-1][:75]
# Jaccard 係数Top 75語をソートして抽出する
group_cross_df = group.iloc[:,sorted_columns]
# プロットする
gssm_utils.plot_wordcloud(" ".join(group_cross_df.columns))
A_レジャー
B_ビジネス
1.11.6 共起ネットワーク図 (カテゴリーごと)¶
# 必要ライブラリのインポート
from scipy.sparse import csc_matrix
for name, group in cross_75_df.groupby(level='カテゴリー'):
print(name)
# 「カテゴリー」ごとに Jaccard 係数でソートする
sorted_columns = np.argsort(jaccard_attrs_df.loc[name].values)[::-1][:75]
# Jaccard 係数Top 75語をソートして抽出する
group_cross_df = group.iloc[:,sorted_columns]
# 共起行列を作成する
X = group_cross_df.values
X = csc_matrix(X)
Xc = (X.T * X)
Xc = np.triu(Xc.toarray())
# 共起行列を DataFrame に整える
group_cooccur_df = pd.DataFrame(Xc, columns=group_cross_df.columns, index=group_cross_df.columns)
# 共起行列の中身を Jaccard 係数に入れ替える
group_jaccard_df = gssm_utils.jaccard_coef(group_cooccur_df, group_cross_df)
# 抽出語の出現回数を取得する
word_counts = group.sum(axis=0).values
# プロットする
gssm_utils.plot_cooccur_network(group_jaccard_df, word_counts, np.sort(group_jaccard_df.values.reshape(-1))[::-1][60])
A_レジャー
<Figure size 800x800 with 0 Axes>
B_ビジネス
<Figure size 800x800 with 0 Axes>
1.11.7 トピック分布 (カテゴリーごと)¶
1.11.7.1 文書全体からトピックを抽出する (LDA)¶
# # 必要ライブラリのインポート
# from sklearn.decomposition import LatentDirichletAllocation as LDA
# # ライブラリ LDA によるトピック抽出
# lda = LDA(max_iter=25, learning_method='batch', random_state=42, n_jobs=-1, n_components=6)
# lda.fit(cross_150_df.values)
# トピックごとに出現確率Top 20語を表示する
n_top_words = 20
feature_names = cross_75_df.columns
for topic_idx, topic in enumerate(lda.components_):
print(f"Topic # {topic_idx+1}:", end=" ")
for i in topic.argsort()[:-n_top_words-1:-1]:
print(feature_names[i], end=" ")
print()
Topic # 1: 温泉 良い 宿 美味しい 部屋 露天風呂 風呂 スタッフ 夕食 素晴らしい 大変 最高 湯 楽しい 気持ちよい 素敵 建物 浴場 お湯 丁寧 Topic # 2: 便利 駅 近い 立地 コンビニ 良い ホテル 徒歩 よい 場所 部屋 安い やすい 値段 静か 大変 アメニティ 多い 無料 ありがたい Topic # 3: 良い 綺麗 部屋 風呂 立地 ホテル やすい 古い 無い 水 高い 残念 トイレ 美味しい 感じ 狭い アメニティ 悪い 安い フロント Topic # 4: ホテル スタッフ フロント 部屋 嬉しい 良い 丁寧 いい 人 アウト 親切 他 女性 感じ 荷物 悪い 多い よい 大変 気 Topic # 5: 部屋 広い 快適 清潔 良い 浴場 ベッド きれい 風呂 ホテル トイレ 十分 狭い ルーム 気 バス よい アメニティ 非常 残念 Topic # 6: 美味しい 風呂 最高 よい 部屋 種類 バイキング 家族 広い おいしい 子供 多い ご飯 残念 夕食 少ない 大変 露天風呂 無料 いい
1.11.7.2 トピックをワードクラウドで描画する¶
# トピックごとに出現確率Top 75語でワードクラウドを作成する
n_top_words = 75
gssm_utils.plot_topic_model(lda, feature_names, n_top_words)
1.11.7.3 トピック分布をプロットする¶
for name, group in cross_75_df.groupby(level='カテゴリー'):
print(name)
# 文書ごとのトピック比率を取得
doc_topic_distributions = lda.transform(group.values)
# 文書全体のトピック比率を計算(平均を取る)
overall_topic_distribution = np.mean(doc_topic_distributions, axis=0)
gssm_utils.plot_topic_distribution(overall_topic_distribution)
A_レジャー
B_ビジネス
1.11.8 本文の参照 (カテゴリーごと)¶
「夕食」「残念」という単語が含まれている口コミを表示する
for name, group in all_df.groupby('カテゴリー'):
print(name)
search_index = group['コメント'].str.contains('夕食') & group['コメント'].str.contains('残念')
display(group[search_index])
A_レジャー
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 16 | A_レジャー | 01_登別 | 39175 | 登別温泉 登別グランドホテル | 4月12日に宿泊しました。記念日に近かったので普段選ばない露天風呂付客室を選びましたが、部屋... | 5 | 4 | 4 | 5 | 4.0 | 5.0 | 5.0 | レジャー | 家族 | 45383 | 投稿者 | na | na | 45400.395394 |
| 23 | A_レジャー | 01_登別 | 40708 | 虎杖浜温泉 ホテル いずみ | 両親と3世代の温泉旅行にこの宿を選びました。部屋の、古さはありましたが、部屋の暖房も良く、清... | 5 | 4 | 4 | 3 | 5.0 | 4.0 | 4.0 | レジャー | 一人 | 45748 | カリばば | 60代 | 女性 | 45778.405301 |
| 32 | A_レジャー | 01_登別 | 28637 | 登別温泉 登別万世閣 | シャンプーが色々な種類があって選べて最高でした。ご時世もあり海外の方が多く、温泉にバスタオル... | 4 | 4 | 4 | 2 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45748 | 投稿者 | na | na | 45775.668414 |
| 65 | A_レジャー | 01_登別 | 18832 | きたゆざわ 森のソラニワ | 夏場なら札幌から車で1:30ほどで到着でき、洞爺湖やルスツにも足を伸ばせる立地。人手不足なの... | 3 | 3 | 5 | 1 | 3.0 | 5.0 | 4.0 | レジャー | 家族 | 45474 | hedwig6284 | 70代 | 男性 | 45488.557685 |
| 93 | A_レジャー | 01_登別 | 40708 | 虎杖浜温泉 ホテル いずみ | 食事は朝食も夕食も、食べきれないくらいのボリューム!どれも美味しかったですし、スタッフの皆さ... | 4 | 4 | 5 | 4 | 2.0 | 4.0 | 5.0 | レジャー | 家族 | 45536 | 投稿者 | na | na | 45557.507164 |
| ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... | ... |
| 4875 | A_レジャー | 05_湯布院 | 180079 | 由布院 玉の湯 | 12年ぶりの宿泊とチェックイン時に教えてくれるメールで確認事項を送ってあったようだけどPCの... | 4 | 4 | 5 | 4 | 4.0 | 4.0 | 4.0 | レジャー | 家族 | 45413 | 投稿者 | na | na | 45454.865984 |
| 4883 | A_レジャー | 05_湯布院 | 184560 | 由布院倶楽部 | 夕食は美味しかったが、朝食のビュッフェが客動線が悪くて待ち時間が長かったのが残念だった。フロ... | 3 | 5 | 3 | 3 | 4.0 | 3.0 | 2.0 | レジャー | 家族 | 45627 | 投稿者 | na | na | 45659.789306 |
| 4934 | A_レジャー | 05_湯布院 | 72793 | 由布院温泉 楓の小舎 | こちらの口コミは参考になりませんでした。夕食:お刺身が臭った。予約時プラン内容説明時点でのお... | 2 | 3 | 4 | 2 | 3.0 | 3.0 | 1.0 | レジャー | 家族 | 45505 | meru20220811 | 40代 | 男性 | 45518.586725 |
| 4942 | A_レジャー | 05_湯布院 | 184593 | 由布院 離れの宿 優夏月 | 11月24日 家族4人で宿泊しました。 久しぶりの家族旅行でとても楽しみにしていた旅行です。... | 3 | 4 | 4 | 3 | 4.0 | 3.0 | 3.0 | レジャー | 家族 | 45597 | 投稿者 | na | na | 45623.930984 |
| 4944 | A_レジャー | 05_湯布院 | 1678 | 由布院温泉 ゆふいん山水館 | 12/1に宿泊しました。オールインクルーシブを楽しみにして、湯布院の宿の中から本旅館にしまし... | 4 | 4 | 4 | 4 | 3.0 | 4.0 | 4.0 | レジャー | 家族 | 45627 | 投稿者 | na | na | 45632.704907 |
111 rows × 19 columns
B_ビジネス
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5188 | B_ビジネス | 06_札幌 | 184541 | ウィンダムガーデン札幌大通 | 飛行機の大幅な遅延のため、予定より4時間チュックインが遅れました。ワンドリンクでアルコールが... | 4 | 4 | 4 | 4 | 3.0 | 3.0 | NaN | レジャー | 友達 | 45717 | 投稿者 | na | na | 45753.671609 |
| 5959 | B_ビジネス | 06_札幌 | 27895 | アパホテル&リゾート〈札幌〉 | 札幌の街より少し郊外ですが、駐車場も無料なので車で行くには丁度良かったです。部屋も広く子ども... | 5 | 5 | 4 | 5 | 5.0 | 4.0 | 4.0 | レジャー | 家族 | 45658 | 投稿者 | na | na | 45682.764120 |
| 9627 | B_ビジネス | 10_福岡 | 180283 | The358 SORA | 子供の誕生日ということもあり、初めて夕食付きのプランで数ヵ月前から予約してました。行く前から... | 3 | 3 | 3 | 4 | 4.0 | NaN | 4.0 | レジャー | 家族 | 45689 | 投稿者 | na | na | 45700.565995 |
| 9631 | B_ビジネス | 10_福岡 | 187154 | Alba HOTEL & Glamping | インスタで見つけてスカイルームのお部屋を予約しました。まず受付で食事などの説明はありましたが... | 3 | 2 | 4 | 4 | 1.0 | 1.0 | 4.0 | レジャー | 一人 | 45505 | 投稿者 | na | na | 45530.491667 |
| 9703 | B_ビジネス | 10_福岡 | 179190 | ガーデンテラス福岡ホテル&リゾート | 夕食、朝食ともに部屋着のまま、のんびり頂きました。1階のラウンジは、飲み物の種類もたくさんあ... | 5 | 5 | 5 | 5 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45444 | 投稿者 | na | na | 45447.790671 |
| 9916 | B_ビジネス | 10_福岡 | 180283 | The358 SORA | 夕食はカニが食べたくて、少し金額の高い「カニ食べ放題」のあるプランにしましたが、ブッフェだっ... | 4 | 5 | 5 | 4 | 4.0 | 5.0 | 5.0 | レジャー | 家族 | 45748 | moppyi | 60代 | 女性 | 45766.753113 |
for name, group in all_df.groupby('カテゴリー'):
print(name)
search_index = group['コメント'].str.contains('夕食') & group['コメント'].str.contains('残念')
print(group[search_index]['コメント'].values[:10]) # とりあえず10件のみ出力
print()
A_レジャー ['4月12日に宿泊しました。記念日に近かったので普段選ばない露天風呂付客室を選びましたが、部屋そのものが広くてゆったりとくつろげました。露天風呂がしっかり分かれていたため湿気の入り込みもなく、人工温泉でもしっかりと温まりました。インバウンドの方が増えてきたため込み合う時間は部屋の風呂、空いている時間は大浴場と使い分けして快適に過ごせました。ご飯も美味しく、夕食のビーフシチュー、朝食の鶏ご飯が好みでした。残念だったのは、ゲームコーナーが故障機種が多かったことくらいですね。普通のお部屋でも十分満足できますが、特別な日に空きがあったらまた利用したいと思います。' '両親と3世代の温泉旅行にこの宿を選びました。部屋の、古さはありましたが、部屋の暖房も良く、清潔感もありました。ただ、日曜日で日帰りのお客様が多いため、両親はゆっくり風呂には入れなかったようです。夕食は、残さず食べましたが、朝食に白老か近いのに、卵料理がないのは残念でした。また、朝食にパンなど選ぶことができたら、良かったと思います。トロトロの最高のお湯質なのに、ゆっくり入ることができないのは、残念した。' 'シャンプーが色々な種類があって選べて最高でした。ご時世もあり海外の方が多く、温泉にバスタオルを巻いて入っていたりしていたので少し残念でした。お部屋は和室にしましたが、古いお部屋だったようでかなり寒かったです。お部屋の角にホコリが溜まっていたりして残念でした。夕食も朝食もバイキングにしましたがお食事は満足です。子供たちも好きなものを好きなだけ食べて満足していました。' '夏場なら札幌から車で1:30ほどで到着でき、洞爺湖やルスツにも足を伸ばせる立地。人手不足なのかレセプションは対面1名のスタッフと、自動チェックイン機が2台のみで、15時は大変混雑するため、夕飯の時間をこだわりたいなら30分前から並ぶ方が良い。地下のプレイパークはチェックイン前から遊べるのが嬉しい。内容は未就学児向けにできていて、体力発散できてとても良い。大浴場も広くて混雑を感じにくい作り。客室は掃除が行き届いておらず、ゴミや髪の毛がかなり落ちていて残念。ソファーの座面パーツが何故か無く、スタッフに持ってきていただいた。これはテンションが下がる…。上の階の足音もかなり響く。20時過ぎても館内放送がかかり騒がしい。夕食のビュッフェは種類が多く、室内もとても広い。遊び場の近くの席なら、ゆっくり食べながら子どもを見守れる。(夕食は席指定ができないが)朝食はパンの種類が少なく、定番の卵料理もなく、夕食と似たようなメニューが並んで、朝食らしさがあまり無い。(朝食は自由席)年に1回で十分かもしれない、また来たい!と思うには客室の清掃状況とチェックイン時の混雑改善がないと難しい。' '食事は朝食も夕食も、食べきれないくらいのボリューム!どれも美味しかったですし、スタッフの皆さんも気持ちのこもったサービスでした。温泉のお湯もトロトロで気持ちよく、肌もすべすべになりました。ただ、建物や設備が古く、部屋のトイレも狭かったので、そこが残念。まわりは木々や緑に囲まれた静かな場所なので、落ち着きます。海に向かったところに東屋があり、ベンチがあります。とても気持ちのいい場所で、しばしのんびりしました。天気のいい日はそこでくつろぐのがおすすめです。' '万世閣って有名なホテルだと知っていたので、とても期待していました。部屋はオシャレな和モダンで良かったのですが、夕食でショックなことがありました。スタッフさんに席に案内され、アルコールの注文の方法など教えてもらいビュッフェコーナーに料理を取りに行って席に戻ってきたらテーブルに見知らぬ料理が・・・。席を間違った他の宿泊客が私達のテーブルに座り、私達の伝票で勝手にお酒を注文していました。伝票には部屋番号と私の名前が記入されていて、ルームキーとの確認の後ビール等を受け取れるのでお酒コーナーの方がちゃんとチェックしていればこんな間違いは起きなかったはず。席のチェンジをしてもらったあとに実際に自分たちもお酒を注文しに行くと当然のことながらルームキーと伝票のチェックはしておらず、最後に伝票にサインしたけどチェックしている様子もありませんでした。席を間違えた客も問題ですが、食事の追加注文分を部屋付けにしているならホテル側がきちんとチェックしなければ間違った客に間違った請求をしてしまうと思います。その後部屋に戻ってからもイライラは収まらずご飯自体も美味しかったのかどうかも覚えてません。フロントスタッフの方に事情を説明し、内容確認等も含めその後の対応はきちんとしてもらいましたが正直残念な気持ちだけが残りました。もし行く予定がある方は夕食時のアルコール注文の確認体制はちゃんと見たほうが良いと思います。' '夕食・朝食ともにバイキングであったが、夕食はおかずも多くおいしかった。浴場は複数あり、のんびりつかることができた。しかし、料金の安い部屋に泊まったため、部屋に洗面所がなかったのが残念でした。' '夕食が期待していた物とは程遠くこれがとても美味しかったというものが無く残念でした。また、お食事の際のテーブルが余りに相手と遠すぎて不思議な感じでした。丁寧なおもてなしをして頂き心地良くのんびり過ごさせて頂いた事は大変評価出来る所だと思います' 'お風呂、朝、夕食大変良かったです。部屋にお茶の茶器が無かったのが残念' '「ゆとりろ洞爺湖」に名前が変わってから2回目の宿泊です。タブレットでのチェックインも一人でできました。ウェルカムドリンク、デザートともに嬉しいサービスです。残念だったのは、夕食に出たセロリの漬物です笑あと、朝食にパンが何種類かあると尚良かった。でも、洞爺湖に行く際はまた泊まりたいです。お世話になりました!'] B_ビジネス ['飛行機の大幅な遅延のため、予定より4時間チュックインが遅れました。ワンドリンクでアルコールが飲めなかったのは残念でしたが、立地が良かったおかげで予約したお店にて夕食をいただくことができよかったです。また、利用したいうと思います。' '札幌の街より少し郊外ですが、駐車場も無料なので車で行くには丁度良かったです。部屋も広く子ども連れだと満足です。子ども料金があったらいいなと思いました。夕食は一階にある、海へへ行きました。季節メニューがほとんど品切れだったのが残念でしたが店員さんはとっても親切で感じ良かったです。朝食は会場も広く種類も豊富でした!' '子供の誕生日ということもあり、初めて夕食付きのプランで数ヵ月前から予約してました。行く前から料理の写真やホテル内の写真、口コミなど見て楽しみにしていました。着いて館内を散策少しだけして待望のディナー、楽しみにしていた国産牛、1回目は早めにできて、2回目取りに行ったら焼くまでに時間かかり、その間他のところ見れたらよかったなーと思いましたが柔らかくはなかったけど、美味しかったです。時間が少し短くあまり堪能できなかったですが、お腹いっぱい食べました温泉は入れませんでしたが部屋のお風呂でも広いしきれいで満足でした1番楽しみにしてた朝御飯、刺身は何回か取りに行っても出来てなかったり、朝はあまりそそるメニューが少なかったです。部屋の隙間にごみやホコリがたまってたのが残念でした' 'インスタで見つけてスカイルームのお部屋を予約しました。まず受付で食事などの説明はありましたが、部屋が何階かなどの説明がなくエレベーターに乗ったときに戸惑いました。スタッフが一緒に部屋まで案内して設備の説明などがあればよかったなとおもいます。また室内プール?やダーツをする遊ぶ場所があるとインスタを見て知っていたのですが、まわりを見てもどこにあるのかわからず説明もなかったので行けずに残念でした。部屋は全体的に狭くシャワーとトイレと洗面台が一緒になっており、すごく使いづらかったです。洗面台で化粧など準備をする際、化粧品などを置く場所がなくて困りました。インスタ映えのお部屋ですごくキレイで良かったのですが、今後女の子同士で泊まった場合化粧などの準備に絶対困るのではないかと思いました。せめて全身鏡を部屋のどこかに設置するなど化粧できるスペースを作った方がいいと思います。ポットなどおいてある棚は無意味に大きすぎて、ポットくらいしか置いてあるものがないのに場所を取りすぎだと思いました。天気がいい日は本当にキレイでプールもあって最高のロケーションだと思います。部屋もクーラーが設置されていて温度調整もできるので快適に過ごせました。夕食のバーベキューもおいしくて量も多く大満足でした。スペースも広くてとてもよかったです。はじめての糸島観光で天気にも恵まれ最高の思い出ができました。' '夕食、朝食ともに部屋着のまま、のんびり頂きました。1階のラウンジは、飲み物の種類もたくさんありましたが、夜、パジャマではいけないので残念でした。' '夕食はカニが食べたくて、少し金額の高い「カニ食べ放題」のあるプランにしましたが、ブッフェだったので、通常の2食付きでもカニを食べられたのではないかと思いました。朝食は素晴らしいの一言でしたが、九州醤油が辛かった。部屋はふたりには丁度良い広さでしたが、椅子にかなり大きいシミがあったのが残念でした。レストランの女性スタッフがとても気が利いていて親切で、気持ちのよいサービスを受けることが出来ました。また絶対に行きたいです。']
【演習】 外部変数を利用したエリアごとの作図¶
2.1 【演習】 ワードクラウド (エリアごと)¶
# ToDo: 1.11.5 のセル中のコードをコピーして貼り付け,「カテゴリー」を「エリア」に変更する
for name, group in cross_75_df.groupby(level='エリア'):
print(name)
# 「カテゴリー」ごとに Jaccard 係数でソートする
sorted_columns = np.argsort(jaccard_attrs_df.loc[name].values)[::-1][:75]
# Jaccard 係数Top 75語をソートして抽出する
group_cross_df = group.iloc[:,sorted_columns]
# プロットする
gssm_utils.plot_wordcloud(" ".join(group_cross_df.columns))
01_登別
02_草津
03_箱根
04_道後
05_湯布院
06_札幌
07_名古屋
08_東京
09_大阪
10_福岡
2.2 【演習】 共起ネットワーク図 (エリアごと)¶
# ToDo: 1.11.6 のセル中のコードをコピーして貼り付け,「カテゴリー」を「エリア」に変更する
# 必要ライブラリのインポート
from scipy.sparse import csc_matrix
for name, group in cross_75_df.groupby(level='エリア'):
print(name)
# 「カテゴリー」ごとに Jaccard 係数でソートする
sorted_columns = np.argsort(jaccard_attrs_df.loc[name].values)[::-1][:75]
# Jaccard 係数Top 75語をソートして抽出する
group_cross_df = group.iloc[:,sorted_columns]
# 共起行列を作成する
X = group_cross_df.values
X = csc_matrix(X)
Xc = (X.T * X)
Xc = np.triu(Xc.toarray())
# 共起行列を DataFrame に整える
group_cooccur_df = pd.DataFrame(Xc, columns=group_cross_df.columns, index=group_cross_df.columns)
# 共起行列の中身を Jaccard 係数に入れ替える
group_jaccard_df = gssm_utils.jaccard_coef(group_cooccur_df, group_cross_df)
# 抽出語の出現回数を取得する
word_counts = group.sum(axis=0).values
# プロットする
gssm_utils.plot_cooccur_network(group_jaccard_df, word_counts, np.sort(group_jaccard_df.values.reshape(-1))[::-1][60])
01_登別
<Figure size 800x800 with 0 Axes>
02_草津
<Figure size 800x800 with 0 Axes>
03_箱根
<Figure size 800x800 with 0 Axes>
04_道後
<Figure size 800x800 with 0 Axes>
05_湯布院
<Figure size 800x800 with 0 Axes>
06_札幌
<Figure size 800x800 with 0 Axes>
07_名古屋
<Figure size 800x800 with 0 Axes>
08_東京
<Figure size 800x800 with 0 Axes>
09_大阪
<Figure size 800x800 with 0 Axes>
10_福岡
<Figure size 800x800 with 0 Axes>
2.3 【演習】 トピック分布 (エリアごと)¶
# ToDo: 1.11.7.2 のセル中のコードをコピーして貼り付け,そのまま実行する
n_top_words = 75
gssm_utils.plot_topic_model(lda, feature_names, n_top_words)
# ToDo: 1.11.7.3 のセル中のコードをコピーして貼り付け,「カテゴリー」を「エリア」に変更する
for name, group in cross_75_df.groupby(level='エリア'):
print(name)
# 文書ごとのトピック比率を取得
doc_topic_distributions = lda.transform(group.values)
# 文書全体のトピック比率を計算(平均を取る)
overall_topic_distribution = np.mean(doc_topic_distributions, axis=0)
gssm_utils.plot_topic_distribution(overall_topic_distribution)
01_登別
02_草津
03_箱根
04_道後
05_湯布院
06_札幌
07_名古屋
08_東京
09_大阪
10_福岡
2.4 【演習】 本文の参照 (エリアごと)¶
# ToDo: 1.11.8 のセル中のコードをコピーして貼り付け,「カテゴリー」を「エリア」に変更する
for name, group in all_df.groupby('エリア'):
print(name)
search_index = group['コメント'].str.contains('夕食') & group['コメント'].str.contains('残念')
display(group[search_index].head()) # 先頭の5件ずつ表示
01_登別
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 16 | A_レジャー | 01_登別 | 39175 | 登別温泉 登別グランドホテル | 4月12日に宿泊しました。記念日に近かったので普段選ばない露天風呂付客室を選びましたが、部屋... | 5 | 4 | 4 | 5 | 4.0 | 5.0 | 5.0 | レジャー | 家族 | 45383 | 投稿者 | na | na | 45400.395394 |
| 23 | A_レジャー | 01_登別 | 40708 | 虎杖浜温泉 ホテル いずみ | 両親と3世代の温泉旅行にこの宿を選びました。部屋の、古さはありましたが、部屋の暖房も良く、清... | 5 | 4 | 4 | 3 | 5.0 | 4.0 | 4.0 | レジャー | 一人 | 45748 | カリばば | 60代 | 女性 | 45778.405301 |
| 32 | A_レジャー | 01_登別 | 28637 | 登別温泉 登別万世閣 | シャンプーが色々な種類があって選べて最高でした。ご時世もあり海外の方が多く、温泉にバスタオル... | 4 | 4 | 4 | 2 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45748 | 投稿者 | na | na | 45775.668414 |
| 65 | A_レジャー | 01_登別 | 18832 | きたゆざわ 森のソラニワ | 夏場なら札幌から車で1:30ほどで到着でき、洞爺湖やルスツにも足を伸ばせる立地。人手不足なの... | 3 | 3 | 5 | 1 | 3.0 | 5.0 | 4.0 | レジャー | 家族 | 45474 | hedwig6284 | 70代 | 男性 | 45488.557685 |
| 93 | A_レジャー | 01_登別 | 40708 | 虎杖浜温泉 ホテル いずみ | 食事は朝食も夕食も、食べきれないくらいのボリューム!どれも美味しかったですし、スタッフの皆さ... | 4 | 4 | 5 | 4 | 2.0 | 4.0 | 5.0 | レジャー | 家族 | 45536 | 投稿者 | na | na | 45557.507164 |
02_草津
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 1054 | A_レジャー | 02_草津 | 5270 | 草津温泉 ホテルヴィレッジ | 基本的には満足です。数点残念な点がありました。夕食のバイキングにて20時入店ステーキの焼き立... | 4 | 3 | 4 | 2 | 2.0 | 4.0 | 4.0 | レジャー | 家族 | 45658 | 投稿者 | na | na | 45680.813067 |
| 1154 | A_レジャー | 02_草津 | 129576 | 草津温泉 大東舘 | 夕食、朝食とも品数があり申し分なし。アルコールが別料金、温泉は思っていたほど臭いがなく残念。... | 4 | 3 | 5 | 4 | 4.0 | 4.0 | 5.0 | レジャー | 一人 | 45748 | はづき1971 | 50代 | 男性 | 45767.665093 |
| 1349 | A_レジャー | 02_草津 | 17837 | 草津温泉 喜びの宿 高松 | 夕食も朝食もとてもおいしかったです。部屋についている冷蔵庫が特殊だったのが少し残念でしたが、... | 5 | 5 | 5 | 5 | 4.0 | 5.0 | 5.0 | レジャー | 恋人 | 45658 | 投稿者 | na | na | 45671.391505 |
| 1372 | A_レジャー | 02_草津 | 5270 | 草津温泉 ホテルヴィレッジ | お風呂と食事が気に入り2回目の宿泊です。前回よりも食事については良かったと思います。夕食の野... | 4 | 3 | 3 | 3 | 3.0 | 4.0 | 4.0 | レジャー | 家族 | 45748 | もっさり6996 | 50代 | 男性 | 45756.431262 |
| 1392 | A_レジャー | 02_草津 | 4904 | 草津温泉 望雲 | 現在リニューアル工事中でしたが、工事が終わっている部分はとてもきれいでよかったです。玄関と回... | 4 | 5 | 4 | 5 | 4.0 | 5.0 | 5.0 | レジャー | 家族 | 45536 | 投稿者 | na | na | 45562.791157 |
03_箱根
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 2024 | A_レジャー | 03_箱根 | 11011 | 富士山を一望できる宿 ホテルグリーンプラザ箱根 | 夕食のビュッフェの質が悪く、写真と違いすぎて食べられませんでした。非常に残念で、旅行の気分に... | 2 | 4 | 4 | 3 | 3.0 | 4.0 | 1.0 | レジャー | 家族 | 45505 | christ20christ@hotmail.com | 30代 | 女性 | 45538.605394 |
| 2026 | A_レジャー | 03_箱根 | 1727 | 富士屋ホテル | 建物が素晴らしいです。スタッフの方々のご対応も素晴らしいのですが、1つ残念なことがありました... | 4 | 4 | 5 | 4 | 4.0 | 4.0 | 4.0 | レジャー | 家族 | 45566 | 投稿者 | na | na | 45586.490116 |
| 2039 | A_レジャー | 03_箱根 | 153202 | 小塚久の葉(旧 箱根仙石原虎乃湯) | 全体的にコスパ含め、満足。こじんまりした宿で静か。子ども連れや外国人をいたが、音は聞こえなか... | 4 | 4 | 4 | 4 | 3.0 | 4.0 | 4.0 | レジャー | 家族 | 45627 | 投稿者 | na | na | 45655.597894 |
| 2047 | A_レジャー | 03_箱根 | 15250 | EN RESORT Re’Cove Hakone(旧:リ・カーヴ箱根) | 家族で1泊しました。チェックイン30分前に到着しましたが、運転に疲れた夫は、welcomeド... | 5 | 5 | 5 | 4 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45658 | まぁちん0206 | 40代 | 女性 | 45675.949433 |
| 2086 | A_レジャー | 03_箱根 | 5081 | 箱根湯本温泉 ホテルおくゆもと | 夫婦でお世話になりました。ホテル全体が清潔で清掃が行き届いており、ゆっくりと時間が流れている... | 5 | 5 | 4 | 5 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45566 | 投稿者 | na | na | 45582.592674 |
04_道後
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 3077 | A_レジャー | 04_道後 | 13653 | 道後温泉 ホテル椿館 | 道後温泉本館や商店街から近い立地なので、とても便利でした。ホテルの温泉も良かったです。接客も... | 5 | 4 | 5 | 4 | 3.0 | 4.0 | 4.0 | レジャー | 一人 | 45352 | ( ^o^ )4649 | 30代 | 女性 | 45377.333252 |
| 3355 | A_レジャー | 04_道後 | 147473 | 大江戸温泉物語 道後 | ゴールデンウィークに家族で利用致しました。ゴールデンウィークなので料金が高いのは理解出来ます... | 2 | 3 | 3 | 3 | 2.0 | 2.0 | 1.0 | レジャー | 家族 | 45778 | ゆんみ2828 | 50代 | 女性 | 45784.632025 |
| 3381 | A_レジャー | 04_道後 | 16719 | 道後温泉 花ゆづき | 食事はすべてわたしたちの口に合ってとても美味しく楽しい時間でした。5歳の娘と一緒でしたが布団... | 4 | 5 | 4 | 3 | 4.0 | 5.0 | 5.0 | レジャー | 家族 | 45689 | 投稿者 | na | na | 45705.684456 |
| 3409 | A_レジャー | 04_道後 | 141611 | オーベルジュ道後 | 道後温泉の中心に程近くゆっくり見て回れます夕食のスタートが20時になってしまいましたが道後温... | 5 | 5 | 5 | 5 | 5.0 | 4.0 | 4.0 | レジャー | 家族 | 45566 | 十郎梅 | 60代 | 男性 | 45594.761806 |
| 3777 | A_レジャー | 04_道後 | 17668 | 道後温泉 茶玻瑠 | 夕食時に提供される無料ドリンクバーの種類が少なすぎて残念でした。できればソフトドリンクや烏龍... | 3 | 3 | 5 | 4 | 3.0 | 5.0 | 3.0 | レジャー | 家族 | 45474 | 投稿者 | na | na | 45499.565394 |
05_湯布院
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 4002 | A_レジャー | 05_湯布院 | 75166 | 由布院温泉 ゆふいん椿 | 夕食は地元の食材を使ったものでとても美味しかった。特に土鍋炊きご飯はおこげもできておいしくお... | 4 | 4 | 3 | 4 | 3.0 | 4.0 | 5.0 | レジャー | 家族 | 45717 | 投稿者 | na | na | 45738.007211 |
| 4007 | A_レジャー | 05_湯布院 | 27922 | 由布院いよとみ | バイク旅で宿泊した宿になります。バイクは屋根下に駐輪させて頂けて感謝しております。部屋は窓、... | 2 | 1 | 4 | 1 | 1.0 | 4.0 | 2.0 | レジャー | 家族 | 45748 | バビロニア28号 | 50代 | 男性 | 45783.687303 |
| 4049 | A_レジャー | 05_湯布院 | 177044 | ゆふいんグランピング COMOREBI | 家族6名で宿泊し、当日は雨模様でとても残念でしたが、贅沢な時間を過ごす事ができました。夕食の... | 5 | 4 | 4 | 5 | 5.0 | 4.0 | 5.0 | レジャー | 家族 | 45352 | 投稿者 | na | na | 45378.703484 |
| 4064 | A_レジャー | 05_湯布院 | 130594 | 由布院温泉 すみか | 母娘の旅行で利用しました。お部屋の露天風呂がやや熱めの湯で、いつとても入浴しても大変気持ち良... | 5 | 5 | 4 | 5 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45658 | グリマスの妻 | 50代 | 女性 | 45686.337616 |
| 4065 | A_レジャー | 05_湯布院 | 145331 | 旅館 由布山 | 夕食はとても美味しくいただきました。内風呂もいつでも入れてとても良かったです。ただ、フロント... | 3 | 2 | 2 | 3 | 3.0 | 4.0 | 4.0 | レジャー | 家族 | 45383 | ふゆのいろ | 60代 | 女性 | 45415.770336 |
06_札幌
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 5188 | B_ビジネス | 06_札幌 | 184541 | ウィンダムガーデン札幌大通 | 飛行機の大幅な遅延のため、予定より4時間チュックインが遅れました。ワンドリンクでアルコールが... | 4 | 4 | 4 | 4 | 3.0 | 3.0 | NaN | レジャー | 友達 | 45717 | 投稿者 | na | na | 45753.671609 |
| 5959 | B_ビジネス | 06_札幌 | 27895 | アパホテル&リゾート〈札幌〉 | 札幌の街より少し郊外ですが、駐車場も無料なので車で行くには丁度良かったです。部屋も広く子ども... | 5 | 5 | 4 | 5 | 5.0 | 4.0 | 4.0 | レジャー | 家族 | 45658 | 投稿者 | na | na | 45682.764120 |
07_名古屋
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 |
|---|
08_東京
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 |
|---|
09_大阪
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 |
|---|
10_福岡
| カテゴリー | エリア | 施設番号 | 施設名 | コメント | 総合 | サービス | 立地 | 部屋 | 設備・アメニティ | 風呂 | 食事 | 旅行の目的 | 同伴者 | 宿泊年月 | 投稿者 | 年代 | 性別 | 投稿日 | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 9627 | B_ビジネス | 10_福岡 | 180283 | The358 SORA | 子供の誕生日ということもあり、初めて夕食付きのプランで数ヵ月前から予約してました。行く前から... | 3 | 3 | 3 | 4 | 4.0 | NaN | 4.0 | レジャー | 家族 | 45689 | 投稿者 | na | na | 45700.565995 |
| 9631 | B_ビジネス | 10_福岡 | 187154 | Alba HOTEL & Glamping | インスタで見つけてスカイルームのお部屋を予約しました。まず受付で食事などの説明はありましたが... | 3 | 2 | 4 | 4 | 1.0 | 1.0 | 4.0 | レジャー | 一人 | 45505 | 投稿者 | na | na | 45530.491667 |
| 9703 | B_ビジネス | 10_福岡 | 179190 | ガーデンテラス福岡ホテル&リゾート | 夕食、朝食ともに部屋着のまま、のんびり頂きました。1階のラウンジは、飲み物の種類もたくさんあ... | 5 | 5 | 5 | 5 | 5.0 | 5.0 | 5.0 | レジャー | 家族 | 45444 | 投稿者 | na | na | 45447.790671 |
| 9916 | B_ビジネス | 10_福岡 | 180283 | The358 SORA | 夕食はカニが食べたくて、少し金額の高い「カニ食べ放題」のあるプランにしましたが、ブッフェだっ... | 4 | 5 | 5 | 4 | 4.0 | 5.0 | 5.0 | レジャー | 家族 | 45748 | moppyi | 60代 | 女性 | 45766.753113 |
for name, group in all_df.groupby('エリア'):
print(name)
search_index = group['コメント'].str.contains('夕食') & group['コメント'].str.contains('残念')
print(group[search_index]['コメント'].values[:10]) # とりあえず10件のみ出力
print()
01_登別 ['4月12日に宿泊しました。記念日に近かったので普段選ばない露天風呂付客室を選びましたが、部屋そのものが広くてゆったりとくつろげました。露天風呂がしっかり分かれていたため湿気の入り込みもなく、人工温泉でもしっかりと温まりました。インバウンドの方が増えてきたため込み合う時間は部屋の風呂、空いている時間は大浴場と使い分けして快適に過ごせました。ご飯も美味しく、夕食のビーフシチュー、朝食の鶏ご飯が好みでした。残念だったのは、ゲームコーナーが故障機種が多かったことくらいですね。普通のお部屋でも十分満足できますが、特別な日に空きがあったらまた利用したいと思います。' '両親と3世代の温泉旅行にこの宿を選びました。部屋の、古さはありましたが、部屋の暖房も良く、清潔感もありました。ただ、日曜日で日帰りのお客様が多いため、両親はゆっくり風呂には入れなかったようです。夕食は、残さず食べましたが、朝食に白老か近いのに、卵料理がないのは残念でした。また、朝食にパンなど選ぶことができたら、良かったと思います。トロトロの最高のお湯質なのに、ゆっくり入ることができないのは、残念した。' 'シャンプーが色々な種類があって選べて最高でした。ご時世もあり海外の方が多く、温泉にバスタオルを巻いて入っていたりしていたので少し残念でした。お部屋は和室にしましたが、古いお部屋だったようでかなり寒かったです。お部屋の角にホコリが溜まっていたりして残念でした。夕食も朝食もバイキングにしましたがお食事は満足です。子供たちも好きなものを好きなだけ食べて満足していました。' '夏場なら札幌から車で1:30ほどで到着でき、洞爺湖やルスツにも足を伸ばせる立地。人手不足なのかレセプションは対面1名のスタッフと、自動チェックイン機が2台のみで、15時は大変混雑するため、夕飯の時間をこだわりたいなら30分前から並ぶ方が良い。地下のプレイパークはチェックイン前から遊べるのが嬉しい。内容は未就学児向けにできていて、体力発散できてとても良い。大浴場も広くて混雑を感じにくい作り。客室は掃除が行き届いておらず、ゴミや髪の毛がかなり落ちていて残念。ソファーの座面パーツが何故か無く、スタッフに持ってきていただいた。これはテンションが下がる…。上の階の足音もかなり響く。20時過ぎても館内放送がかかり騒がしい。夕食のビュッフェは種類が多く、室内もとても広い。遊び場の近くの席なら、ゆっくり食べながら子どもを見守れる。(夕食は席指定ができないが)朝食はパンの種類が少なく、定番の卵料理もなく、夕食と似たようなメニューが並んで、朝食らしさがあまり無い。(朝食は自由席)年に1回で十分かもしれない、また来たい!と思うには客室の清掃状況とチェックイン時の混雑改善がないと難しい。' '食事は朝食も夕食も、食べきれないくらいのボリューム!どれも美味しかったですし、スタッフの皆さんも気持ちのこもったサービスでした。温泉のお湯もトロトロで気持ちよく、肌もすべすべになりました。ただ、建物や設備が古く、部屋のトイレも狭かったので、そこが残念。まわりは木々や緑に囲まれた静かな場所なので、落ち着きます。海に向かったところに東屋があり、ベンチがあります。とても気持ちのいい場所で、しばしのんびりしました。天気のいい日はそこでくつろぐのがおすすめです。' '万世閣って有名なホテルだと知っていたので、とても期待していました。部屋はオシャレな和モダンで良かったのですが、夕食でショックなことがありました。スタッフさんに席に案内され、アルコールの注文の方法など教えてもらいビュッフェコーナーに料理を取りに行って席に戻ってきたらテーブルに見知らぬ料理が・・・。席を間違った他の宿泊客が私達のテーブルに座り、私達の伝票で勝手にお酒を注文していました。伝票には部屋番号と私の名前が記入されていて、ルームキーとの確認の後ビール等を受け取れるのでお酒コーナーの方がちゃんとチェックしていればこんな間違いは起きなかったはず。席のチェンジをしてもらったあとに実際に自分たちもお酒を注文しに行くと当然のことながらルームキーと伝票のチェックはしておらず、最後に伝票にサインしたけどチェックしている様子もありませんでした。席を間違えた客も問題ですが、食事の追加注文分を部屋付けにしているならホテル側がきちんとチェックしなければ間違った客に間違った請求をしてしまうと思います。その後部屋に戻ってからもイライラは収まらずご飯自体も美味しかったのかどうかも覚えてません。フロントスタッフの方に事情を説明し、内容確認等も含めその後の対応はきちんとしてもらいましたが正直残念な気持ちだけが残りました。もし行く予定がある方は夕食時のアルコール注文の確認体制はちゃんと見たほうが良いと思います。' '夕食・朝食ともにバイキングであったが、夕食はおかずも多くおいしかった。浴場は複数あり、のんびりつかることができた。しかし、料金の安い部屋に泊まったため、部屋に洗面所がなかったのが残念でした。' '夕食が期待していた物とは程遠くこれがとても美味しかったというものが無く残念でした。また、お食事の際のテーブルが余りに相手と遠すぎて不思議な感じでした。丁寧なおもてなしをして頂き心地良くのんびり過ごさせて頂いた事は大変評価出来る所だと思います' 'お風呂、朝、夕食大変良かったです。部屋にお茶の茶器が無かったのが残念' '「ゆとりろ洞爺湖」に名前が変わってから2回目の宿泊です。タブレットでのチェックインも一人でできました。ウェルカムドリンク、デザートともに嬉しいサービスです。残念だったのは、夕食に出たセロリの漬物です笑あと、朝食にパンが何種類かあると尚良かった。でも、洞爺湖に行く際はまた泊まりたいです。お世話になりました!'] 02_草津 ['基本的には満足です。数点残念な点がありました。夕食のバイキングにて20時入店ステーキの焼き立てや天ぷらの揚げたてが食べたかったのですが全て作り置きステーキについては、温め直しもなく温かいからと渡されたモノは冷たく残念でした。お部屋にて素晴らしいお部屋なのですが天井や床にブルーベリー?のシミがまた2歳の子供がいる事も事前に知らせているので浴衣を用意頂くのは有り難かったのですが出来れば、スリッパや布団を敷くかの質問、もしくはベビーガードが部屋にあると、有り難かったです。' '夕食、朝食とも品数があり申し分なし。アルコールが別料金、温泉は思っていたほど臭いがなく残念。受付がいまいち。でも料金を考えると満足。' '夕食も朝食もとてもおいしかったです。部屋についている冷蔵庫が特殊だったのが少し残念でしたが、それ以外はとてもよかったです。また行きたいと思える場所でした、ありがとうございました。' 'お風呂と食事が気に入り2回目の宿泊です。前回よりも食事については良かったと思います。夕食の野菜、お寿司、フォー、上州牛やステーキと朝食のオムレツとキムチ梅干しとカレールーが気に入っています。お風呂は何度でも入りたいと思うほど気に入っています。部屋からもう少し近ければとは思います。リゾートパスポートは以前よりも遊べるものが少なくて残念でひた。' '現在リニューアル工事中でしたが、工事が終わっている部分はとてもきれいでよかったです。玄関と回廊にプロのフラワーアレンジメントが入り、雰囲気アップでした。温泉バスターミナル到着後、宿に電話をするとすぐ迎えに来てもらえました。帰りも送ってもらえました。湯畑まで坂を降りてそう遠くなく散策にも便利でした。夕食はお部屋、朝食は個室でゆっくり出来ました。周りに飲食店がたくさんあるので、素泊まりで食事に出るのもいいなと思いました。お風呂が3箇所あり、1泊だと全部に入りきれなかったのが残念でした。また、階段が少々多めだったこと、エレベーターがわかりにくかったこと、草津の特性ですが坂が多いことが、高齢者には大変かなと思いました。総合的には満足でまたぜひ利用したい宿です。' '2人の娘ファミリーと10人で利用させてもらいました。気に入った点は部屋に入れないけど到着したらチィックインができてバスを利用してスキー場に行って遊べた点です。11時のチェックアウト後も同じでプールやお風呂を利用できた点は本当に有り難かったです。また、お部屋も広々としていて毎年2回ほど皆で旅行していますが今までで一番良かったです。夕食も朝食もバイキングでしたが本当に美味しくて無くなれば直ぐに補充されて大きなホテルに有りがちなどこか機械的な淋しい感じは一切なく温かな雰囲気の中皆に大好評でした。何よりスタッフの方が行き届いたサービスをされていて凄いと感じました。ただ一つ残念なのはスキー場行きのバスも駅行きのバスも皆同じバス乗り場になっていてドライバーさんがどこ行きと言ってくれないのでホテルの人はわかっているでしょうが初めて利用する客は分からないので口頭でどこ行きと言ってもらえたら分かりやすくて有り難いと思いました。また、大きいホテルなので仕方ないかもしれませんがエレベーターを降りてからお風呂迄が遠く感じました。ウェルカムドリンクが無いことや部屋や大浴場のアメニティが最小限であること、タオルも返却する事などはありますが、それ以上に気遣いが感じられてとても良いホテルだと思いました。また、機会があったら是非泊まりたいです。' '【非常に残念でした】伝えていたアレルギーの食材を出されて、症状が出た時謝罪もないのはもう終わりだと思いました。特別な記念日に、新しくできた客室に宿泊。部屋自体はサウナに半露天でキレイでよかったのですがそれ以外全て最低でした。まず、夕食も一番いいコースにしたのですがあまり美味しくない。それはまだしも、事前に伝えていたアレルギーの食物(梅やリンゴ、桃と豆乳や大豆製品)を食前酒の梅酒から提供されました。スタートからそのせいで少し喉に痒みがあり不快だったなかで、それ以降も湯葉こんにゃく、梅の入った珍味、など続々とわかりにくくなんのアナウンスもなしに提供され、アレルギー症状が強くなりました。入っていないはずなのに、とメニューを確認すると梅や湯葉という記載があり、変更されていない事実が発覚しました。後から確認したら謝罪の前に梅酒は出してしまいましたが湯葉こんにゃくは湯葉入ってないです、梅の珍味もあれは梅ではなくマンゴーです。と。写真も掲載しますが、湯葉こんにゃくも梅も確認できます。そもそも、梅酒を出している時点でなのですが…私は軽度の症状で当日体調不良だけでしたがもしそばやナッツ、甲殻類アレルギーのもっと酷い人にこれをしていたらと思うとゾッとします。それ以外にも、突然食事している横でカメラクルーが何のアナウンスもなく入ってきて、撮影を開始し、こちらは会話できないディナータイムになって、いつ終わるのかも伝えられず飲食店の外にも出られませんでした。諸々あり、翌朝は朝ごはんも食べられませんでした。帰り際上記を伝えると謝罪の一言もなく、入湯税などのお金を払ってくださいとだけ言われました。流石に、アナフィラキシー症状だされて特別な日のディナーをめちゃくちゃにされてがっかりしました。翌日電話で改めて確認や問題だったところを伝えたら食品は上記の言い訳をして謝罪もなく返金すらせずでした。お子さんやアレルギーのある方は気をつけて欲しいです。新客室と立地は良いので部屋の利用、素泊まりはいいかと思いますが、トータルで見ると値段には見合ってません。' '初めての草津温泉でとても評価の高いホテル櫻井様に宿泊。ホテルに車で入るとベルボーイさんが駐車スペースに案内してくれました。直ぐにポーターさんが車に来て荷物を下ろして頂きフロントまで運んでもらい手際の良さにビックリしました。またベルボーイさんの駐車場案内が非常にスピーディーで最高級シティホテルに来たイメージでした。フロントでのチェックインも非常にスムーズで館内及び夕食・朝食の説明さらにはクラブラウンジの説明も丁寧にして頂きました。さくらラウンジは14;00~19;30の利用時間で豊富なドリンク・アルコールと軽食が楽しめます。オードブルが無くなるので早めに行くことをお薦めします。さくらラウンジのスタッフの方も非常に親切でした。お風呂にはハイスペックなマッサージチェアーもあり非常にリラックス出来ました。ブッフェも品数は豊富でさらにはオープンキッチンでわくわく感や満足感がありました。非常に残念だったのがフリードリンク。ブッフェ案内時に日本人女性スタッフからフリードリンクのオーダーは19;30スタートなので21;00まで言われました。会場の利用は21;30までと。20;30過ぎにドリンクのラストオーダーを言われて隣の席の方もビックリされていて再度確認すると21;00まで言われましたがオーダードリンクを持ってきたドリンクコーナー担当の日本人の男性スタッフからこのオーダーで最後にして下さいと打ち切り。沢山良いところがあるホテル櫻井様には申し訳ありませんが非常残念なスタッフ1人でつまらない宿泊になることもありますのでハード面だけでなくソフト面もしっかり教育をお願いします。さすがに東の大関と評価されるホテル櫻井様でした。次回は懐石とフリードリンクなしで宿泊します。' '夜の湯畑に行きたかったので近いそちらを選びました。部屋は広く綺麗で、宿の方々は女性も男性もとても感じが良く、とくに食事の給仕をしてくださった女性スタッフの可愛いく丁寧な事。気持ち良く過ごせました。朝夕の食事は満足。ただ夕食の時間はチェックイン順で決まり「あと30分遅く」と希望しても断固として聞き入れられなかったので、遅め夕食がいい方は遅めのチェックインがいいかも。部屋周りはとても静かでそれはいいのですが、窓の外は樹木や石積みが高く迫り、怖くて障子を開けられなかったのが残念です。' '5月19日に母と宿泊しました。まだ新しく綺麗でした。湯畑にも近いですし、お夕食先も近くフリードリンクもあり大変満足しました。ただ一つ、お部屋の露天風呂がぬるいお湯でしたので残念です。'] 03_箱根 ['夕食のビュッフェの質が悪く、写真と違いすぎて食べられませんでした。非常に残念で、旅行の気分に影響を与えました。 7:15、8:15にはすでに食べ物の持ち帰りが始まっていました。料金は高いです。' '建物が素晴らしいです。スタッフの方々のご対応も素晴らしいのですが、1つ残念なことがありました。夕食時にボトルワインの白をオーダーし、度々スタッフの方が注いでくれます。三杯目を頂いてましたところ、小さな虫が白ワインに入ってしまいそのことをスタッフに伝えたところ、グラスをさげ新しいグラスを持ってきてくれワインを注いでくださりました。さげていただきましたグラスには結構ワインが残っていたので、とても損した気分になりました。何か一杯サービスしてくれてもいいのではないか?と感じました。グラスワインを頼んだ場合だったらどうなるの?と思ってしまいました。歴史あるとても素敵なホテルなだけに、とても残念でした。' '全体的にコスパ含め、満足。こじんまりした宿で静か。子ども連れや外国人をいたが、音は聞こえなかった。夕食はしゃぶしゃぶコースだったが、しゃぶしゃぶの肉野菜ともボリュームがあってよかった。朝食は釜で炊いたご飯が1膳だけだったのが残念。改善してほしいのは、共用部廊下食堂などの暖房。寒いので朝食にダウンを着ていた人がいた。温泉も宿泊人数に対して十分な広さだったゆっくりくつろげた。年末年始の箱根の宿泊料金を考えれば大満足でした。' '家族で1泊しました。チェックイン30分前に到着しましたが、運転に疲れた夫は、welcomeドリンク以外にビールやハイボールがあるのが嬉しかったようで、とても喜んでいました。リニューアルエリアはとても落ち着いた雰囲気で、夕食後にボードゲームと卓球を2時間楽しみました。いつも旅行に行くと部屋でぼーっと過ごしてしまうのですが、家族で大笑いしながら過ごせた時間はとても貴重でした。お部屋の広さは十分でしたが、部屋の作りの関係でソファーベッド側の照明が付け方が分からなかったり、位置的に明るすぎるきがしました。加湿器もフロントにお願いして持ってきて頂きましたが、暖房がかなり効いているので、この季節はお部屋に常設でもいいかな?と思いました。お食事は、大変満足できる内容でした。和洋中、品ぞろえが豊富でした。1点残念だと思ったのは、小さいお子さんたちが手を触れられるところにお皿やカラトリーがあるところです。(デザートゾーン)本来なら親御さんが注意すべきだと思いますが、2歳程度のお子さんがお皿やカラトリーを触っていた事が気になりました。' '夫婦でお世話になりました。ホテル全体が清潔で清掃が行き届いており、ゆっくりと時間が流れている感じでした。温泉もサラッとしていながら肌がスベスベになる泉質で気持ちが良かったです。大浴場はアメニティーにも気配りがされており、私の好きなミキモトのシャンリンもありました。また、夕食時は、ワンドリンクのサービスが有るプランで、私はビール、夫は赤ワインをいただきました。天麩羅とステーキは追加し放題で、タッチパネルでオーダー出来、何回も持って来ていただけるので助かりました。ステーキは焼き方(ミディアムレア、ウェルダン等)も選択可能なので大満足です。朝食はバイキングで食材が豊富です。私は新鮮な野菜サラダと焼き立てのクロワッサンが、とても美味しかったです。一つ残念だったのは、自販機のミネラルウォーターが品切れで、何回かフロントにご足労をお掛けした事です。もう少し自販機の在庫を増やしていただければと思いました。機会があれば是非再訪させて頂きたいと思います。' '今回は一人旅で強羅の濁り温泉に入り、美味しい食事を食べ、まったりしたいという条件で天翠茶寮さんに決めました。15時にチェックインし即楽しみにしていた温泉へ。内湯は温泉ではないということがわかっていましたので、露天風呂へ。足を入れたとたん悲鳴。冷たくて入ることができません。先客でいらした内湯にいた方も同様で驚いたとのこと。その方がフロントに露天風呂に入れないことを告げました。宿の方が来て何やら点検し、温泉の供給元に連絡するので夕方には熱くなるとのことでした。夕食後熱くなっていることを期待して浴場へ行きましたが、相変わらず露天風呂は冷たく入ることができません。フロントに連絡しましたが答えは供給元に連絡すると昼間と同じ回答。もう諦めました。結局天翠茶寮では温泉に入ることができませんでした。チェックアウトの際、女将のような方が対応してくださいましたが、謝罪の言葉も全くなく残念でした。きっと上司の方には伝わっていなかったのかな。天翠茶寮さんも高級旅館の部類で宿泊料も高い設定です。価格に見合ったサービスを期待したいです。' '個室露天風呂付のお宿には幾度となく宿泊していますが、過去最高に気持ちの良いロケーションと温泉を堪能できました。食事につきましては夕食の量が少なかったのが少しだけ残念だったので星4つとさせて頂きます。味的には星5です。同価格帯の創作和食のお宿の平均と比較して1~2割くらい少なく感じます。全体的にとても美味しく、味は文句の付けようの逸品揃いです。味、盛り付け、お皿(料理長殿の趣味とお聞きしました)は大変素晴らしいです。妻は今までで1番好きと言っていました。出汁を堪能する優しめの味付けなので濃い味が好きな方には物足りないかもしれませんが、個人的には大満足です。美味しかった故に物足りなさもあるのかもしれませんが、メイン(強肴)とお米(食事)が他のお宿に比べて控え目な量かなぁと。2~3万円クラスのお宿だとむしろ夕食にコスト全振りみたいなところが多いので量が物足りなく感じてしまいます。お米がとても美味しかったので、おかわりが出来たら嬉しいかも…。また、量のアップグレードが出来るプランがあったら嬉しいですね。年配の方やお酒を主軸に楽しむ方には丁度いいかな?とも思いますが、海外の方や若い方だと物足りないかも知れません。妻でも少なく感じたと言うくらいの量なので女性でも控えめに感じる方はいると思います。しかし夜は少なめにと言うほうが健康的ではあるので、食べすぎ夫婦による完全なる我儘ですね笑相対して朝食はとてもボリュームがあり、味は過去宿泊したお宿の中で1番良かったと夫婦で意見が一致しております。また、配膳の担当をしてくれたスタッフさんや受付の方も大変感じが良く親切でした。お食事や紅茶について質問をしたりお忙しい中でお手間をかけてしまいましたが、嫌な顔をせず終始明るく親切に接して頂けて大変嬉しく思いました。色々と話が飛んでしまいましたが…まとめとしまして、総合的に大満足のお宿でした。部屋も高級感があり非現実的な雰囲気を体験できます。少々お高いですが何度も行きたいと思える時間を楽しむ事ができました。また伺いますのでよろしくお願い致します。' '9月初旬の利用で、ツツジは見れませんでしたが、緑の森に囲まれ、すき透った芦ノ湖の前に立つ広大な敷地のホテルは、すべての面で素晴らしかったです。建物は少し古く感じますが、趣があり、また水回りは改装されていて快適でした。夕食のすき焼と朝食のオリジナルフレンチトーストを頂きましたが、どちらも大変美味しく頂けました。一点残念だったのは浴槽が樹脂製の1ランク下のモノだったので、そこが質感を下げていて残念でした。' '結婚記念日の記念旅行として宿泊させて頂きました。一番驚いたことは、夕食の旬粋会席が何を食べてもとても美味しかったことです。温泉は、大浴場に露天風呂がないことは残念ですが、今回は貸し切り露天風呂の予約を取ることができて、ゆっくりと楽しめました。また、ウェルカムドリンクが充実していることや強羅駅からの送迎サービスも大変助かりました。また、泊まりに来たいと思えた宿です。' '1/12に1泊、家族三世代5名で利用しました。元箱根港のバス停に近く、コンビニもほぼ目の前にありとても便利で、レイクビューで富士山も目の前に広がりとてもいいロケーションでした。個室の風呂も窓を開ければ富士山が見え、浴槽の木の香りも相まってとてもいい雰囲気でお風呂を楽しめました。夕食、朝食付きで全て用意されており、簡単な調理で準備ができ、バーベキュー設備がありましたが、寒くても室内の調理器具で充分美味しく楽しめました。量・質ともに満足できました。ただオーブンやコーヒーメーカーはマニュアルがあるとより便利かと感じました。全て施設内で完結できる便利さもウリだと思いますが、有料で購入できる追加の飲み物、軽食の販売機で、一部に賞味期限切れの商品があったため、全ての商品が購入できなくなるのは不便でした。お酒を買いたいだけなのに、結局、コンビニに買い物に行くことになりました。全体的な体験価値は良いので、そこだけが非常に残念に感じました。'] 04_道後 ['道後温泉本館や商店街から近い立地なので、とても便利でした。ホテルの温泉も良かったです。接客も丁寧にして頂き、ご飯も朝夕ともお腹いっぱい食べることができました。美味しかったので、お土産にバイキングに出ていたホテルオリジナルの海苔たくさん買って帰りました!夕食の実演の貝を焼いたものや、コーヒー(2台とも)が品切れで家族が残念がっていました。' 'ゴールデンウィークに家族で利用致しました。ゴールデンウィークなので料金が高いのは理解出来ますが…夕食のクオリティが低いです。温泉も本当に温泉?なのかなって思いました。バスタオルもガチガチに硬い…ちょっと残念でした。' '食事はすべてわたしたちの口に合ってとても美味しく楽しい時間でした。5歳の娘と一緒でしたが布団・食事なしで十分でした。夕食・朝食ともにバイキングがあり食べる量も調節しやすく肉好きなので伊予牛の美味しさに目を見開いていました。部屋も館内の程よく暖かく、シングル布団に添い寝でも畳なのではみ出ても問題なしで寒気も感じませんでした。別の方の口コミで館内が少し古いとありましたのである程度、覚悟していました。それと道後温泉はそもそも歴史のある温泉なのでそこも特徴かなと思います。古いの仕方がないのですが、部屋の扉を開閉は、「靴を収納しないと扉の開閉ができない状況」でした。ここだけが不便で残念でしたので、総合評価4点です。' '道後温泉の中心に程近くゆっくり見て回れます夕食のスタートが20時になってしまいましたが道後温泉本館の空いている時間帯に入ることもでき良かったです夕食のイタリアンは大変美味しかったのですが料理の提供に時間がかかったのが残念でした朝食は和食でこれも大変美味しかったのですが小鉢が各自異なっておりとまどいました滞在中のラウンジのソフトドリンク飲み放題は嬉しかった' '夕食時に提供される無料ドリンクバーの種類が少なすぎて残念でした。できればソフトドリンクや烏龍茶なども選べると嬉しいです' 'お誕生日旅行で家族4人で行きました!子どもは蛇口をひねって出るジュースに大喜びでした!夕食もどれも美味しく、サプライズでケーキをお願いしてたのですが、ホールケーキのイチゴも甘くとても美味しかったです!お風呂は夜入った時は露天風呂が広かったのですが、朝入った方は露天風呂が狭かったです。あと部屋の鏡に大きめの傷があったのが少し残念でした、'] 05_湯布院 ['夕食は地元の食材を使ったものでとても美味しかった。特に土鍋炊きご飯はおこげもできておいしくお代わりして満腹でした。温泉風呂付の部屋だったので何回も温泉入って体が癒されました。ただし杉材の風呂でしたが湯漏れがしていたのがちょっぴり残念でした。' 'バイク旅で宿泊した宿になります。バイクは屋根下に駐輪させて頂けて感謝しております。部屋は窓、ロールカーテンにはカビがありました。ベッドはスプリングが悪く、寝返りのたびにギーギー音が鳴り、よく寝れませんでした。夕食は調理されていることだったのですが、温かく食べるものも冷たいものが多く、正直残念な気持ちになります。また、配膳されるお椀に指を入れて配膳されるたことがメチャクチャ気になりました。何より一番残念に思ったのが、飲み物の注文がQRコードからの注文だったことです。旅館に宿泊したのも、現実から離れたい、という思いもあるのに、町中の居酒屋のようなシステムに何か違うのではないか、手間を省いてはいけないものを省いているのではないかと思いました。朝食は美味しかったけど、残念なことが多かった旅館でした' '家族6名で宿泊し、当日は雨模様でとても残念でしたが、贅沢な時間を過ごす事ができました。夕食のボリュームも、とてもあったので、初めにサーロインとヒレ肉を食べておけば良かったと後悔。夜食やプレゼントを沢山もらえ、とても良かったです。' '母娘の旅行で利用しました。お部屋の露天風呂がやや熱めの湯で、いつとても入浴しても大変気持ち良く、お食事もそれぞれに上等な素材が使われており、美味しかったです。施設はまだ新しく、各設備はお掃除が行き届いておりとてもきれいでした。立地は車でしか行けない場所なので少々不便ですが駐車場も停めやすくレンタカー使用の私たちには問題ありませんでした。外国人団体客がおらず大変静かに過ごせます。ひとつだけ残念だったのは朝、夕食とも「ご飯のお替りができますよ」と声をかけてもらえなかったことでしょうか。ご飯(お米)が多変美味で、若い娘はもう少し食べたかったようですがお替り可能かわからず(一品ずつ提供されるスタイルでしたので)遠慮して声をかけられませんでした。食事の終わりごろにお替りをしている男性がいて、「ああ、声をかければよかった」と悔しがっていました。女性ふたりだからあまり食べないだろう、と思われたのかな。男性はご飯の量が少なく感じるかも。でも、またぜひ利用したい温かいおもてなしのお宿です。' '夕食はとても美味しくいただきました。内風呂もいつでも入れてとても良かったです。ただ、フロントもなく迅速なスタッフの方の対応等もなく残念でした。考えてた湯布院の旅館とかけ離れていて悲しい気持ちで帰りました。' '受け付けも案内してくださった方も穏和な方で安心できました。お部屋もすごく素敵で良かったです。夕食のお肉の多いこと!!ビックリしました。お風呂も石風呂で風情があり、のんびり過ごすことができました。ひとつだけ残念だったのが、ベット横の間接照明が少し埃っぽかったこと。でもまた行きたいと思えるコテージでした。' '玄関前に到着するとすぐに出迎えがあり、案内もとてもスムーズでした。サービスが非常に行き届いており、苦手なものをヒアリングして夕食時から変更してくださったのには驚きました。部屋の設備の案内も過不足なく、ゆったりと過ごすことができました。ありがとうございました。【部屋】こちらの部屋しか空いていなかったのですが、寝室が二部屋あり家族で宿泊するのに適しています。夫婦2人でしたので、もったいない空間でした。部屋の温泉も掃除が行き届いていて、脱衣所も浴室もとても広く、ゆったり寛ぐことができました。【食事】志向をこらした味、盛り付け、全て素敵でした。量も満足です。素材もとても良質で、素材を活かした味でとても美味しくいただきました。朝食のだし巻き卵、筑前煮がとても美味しかったです。サラダもとても彩りがきれいで、ドレッシングもこだわって作られており、また是非食べたいです。【その他施設】チェックインが遅く、アウトが早かったのでラウンジ等は使用できませんでしたが、とても素敵な空間でした。【その他】毎年、夫婦が誕生日が近いため奮発した旅行に出かけています。宿泊カードに夫の誕生日を記載したところ、誕生月だからとロールケーキのサービスがあり感激しました。おそらく、案内係の方にロールケーキの話をしていて、持ち帰りできないと残念に思っていたのを汲んでくださり、誕生日ケーキとして出してくださったのだと、そのお心遣いがとても嬉しかったです。そのような少しの会話の中から、最善のサービスをしてくださるお宿です。また九州に訪れる時には絶対にお世話になりたいです。ありがとうございました。' '部屋は良かったがお部屋の露天風呂のシャワーの出が悪く髪も洗えない位に弱かった、仕方なく湯船からの湯を使った。また食事処で夕食、朝食の注意書きみたいのがあったが、浴衣の袖を留めるゴムや朝の柚子胡椒などこちらから言わないと出てこない、机の上に置いてあると記載があった。少しチグハグさを感じた。その他食事や部屋には満足だっただけに残念である。' '愛犬を連れての湯布院旅行旅館はリフォームされているので、大変綺麗です夕食も朝食もワンコを連れて行けます夕食は美味しかったですが朝食のビュッフェ?バイキング?が、おかずの種類が少なく残念でした立地は観光するお土産屋さんのすぐ近くなのでチェックアウトした後も車を停めさせてくれて軽く散歩したりお土産買ったり最後まで楽しめましたチェックインの時は観光客が多くない道を聞いた方が良いです!聞いても私達は観光客の中に車で突込んでしまい大変でしたスタッフさんは皆さん笑顔でワンコにも声を掛けてくれて居心地の良い旅館でしたワンコのご飯にオシッコシートなど必要な物はご持参で~~♪' '2月17日に宿泊しました。夕食メインのしゃぶしゃぶが残念でした。鍋つゆがとても塩辛く(海水より塩辛い)お肉をしゃぶしゃぶした後にポンズをつけると更に塩辛く食べれませんでした。ポンズやゴマダレで食べるしゃぶしゃぶの鍋つゆは昆布だし等でだしをとるだけで、塩分は入れないものではないでしょうか。ゆふいん亭のオリジナルのしゃぶしゃぶがそうであれば良いと思いますが、食べられない程の塩辛いのは残念です。鍋つゆに使用する顆粒だし?が間違いかと確認しましたが、お湯で薄めて食べて下さいとの対応でした。ちなみに鍋つゆを2倍ぐらいに薄めても塩辛く食べれませんでした。料理される方は味見され提供されているのでしょうか?交換してもらった鍋つゆは薄い塩味でしたがそれでも塩味がキツイと思いました。また、チェックアウト時に、そのことは何もなかったように一言も触れない対応も合わせて残念でした。せっかく楽しみにしていた湯布院温泉旅行ががっかりでした。'] 06_札幌 ['飛行機の大幅な遅延のため、予定より4時間チュックインが遅れました。ワンドリンクでアルコールが飲めなかったのは残念でしたが、立地が良かったおかげで予約したお店にて夕食をいただくことができよかったです。また、利用したいうと思います。' '札幌の街より少し郊外ですが、駐車場も無料なので車で行くには丁度良かったです。部屋も広く子ども連れだと満足です。子ども料金があったらいいなと思いました。夕食は一階にある、海へへ行きました。季節メニューがほとんど品切れだったのが残念でしたが店員さんはとっても親切で感じ良かったです。朝食は会場も広く種類も豊富でした!'] 07_名古屋 [] 08_東京 [] 09_大阪 [] 10_福岡 ['子供の誕生日ということもあり、初めて夕食付きのプランで数ヵ月前から予約してました。行く前から料理の写真やホテル内の写真、口コミなど見て楽しみにしていました。着いて館内を散策少しだけして待望のディナー、楽しみにしていた国産牛、1回目は早めにできて、2回目取りに行ったら焼くまでに時間かかり、その間他のところ見れたらよかったなーと思いましたが柔らかくはなかったけど、美味しかったです。時間が少し短くあまり堪能できなかったですが、お腹いっぱい食べました温泉は入れませんでしたが部屋のお風呂でも広いしきれいで満足でした1番楽しみにしてた朝御飯、刺身は何回か取りに行っても出来てなかったり、朝はあまりそそるメニューが少なかったです。部屋の隙間にごみやホコリがたまってたのが残念でした' 'インスタで見つけてスカイルームのお部屋を予約しました。まず受付で食事などの説明はありましたが、部屋が何階かなどの説明がなくエレベーターに乗ったときに戸惑いました。スタッフが一緒に部屋まで案内して設備の説明などがあればよかったなとおもいます。また室内プール?やダーツをする遊ぶ場所があるとインスタを見て知っていたのですが、まわりを見てもどこにあるのかわからず説明もなかったので行けずに残念でした。部屋は全体的に狭くシャワーとトイレと洗面台が一緒になっており、すごく使いづらかったです。洗面台で化粧など準備をする際、化粧品などを置く場所がなくて困りました。インスタ映えのお部屋ですごくキレイで良かったのですが、今後女の子同士で泊まった場合化粧などの準備に絶対困るのではないかと思いました。せめて全身鏡を部屋のどこかに設置するなど化粧できるスペースを作った方がいいと思います。ポットなどおいてある棚は無意味に大きすぎて、ポットくらいしか置いてあるものがないのに場所を取りすぎだと思いました。天気がいい日は本当にキレイでプールもあって最高のロケーションだと思います。部屋もクーラーが設置されていて温度調整もできるので快適に過ごせました。夕食のバーベキューもおいしくて量も多く大満足でした。スペースも広くてとてもよかったです。はじめての糸島観光で天気にも恵まれ最高の思い出ができました。' '夕食、朝食ともに部屋着のまま、のんびり頂きました。1階のラウンジは、飲み物の種類もたくさんありましたが、夜、パジャマではいけないので残念でした。' '夕食はカニが食べたくて、少し金額の高い「カニ食べ放題」のあるプランにしましたが、ブッフェだったので、通常の2食付きでもカニを食べられたのではないかと思いました。朝食は素晴らしいの一言でしたが、九州醤油が辛かった。部屋はふたりには丁度良い広さでしたが、椅子にかなり大きいシミがあったのが残念でした。レストランの女性スタッフがとても気が利いていて親切で、気持ちのよいサービスを受けることが出来ました。また絶対に行きたいです。']